תוכן עניינים
- 1 דרישות מערכת
- 2 דרישות מכם
- 3 איך להתקין Composer ב – Windows
- 4 מדריך התקנה ב – Linux / Unix / OSX
- 5 מוכנים? בואו נלחין קצת PHP עם Composer!
- 6 PasswordApi
- 7 בונוס: להקים שרת מקומי עם המסוף
- 8 CHEATSHEET: פקודות נפוצות למסוף
- 9 זה לא הסוף..
Composer הוא הכלי הפופולרי ביותר לניהול תלויות (Dependency management) בפרוייקט שמפותח בשפת PHP; הכלי מופעל במסוף (CLI).
השימוש בו רווח מאד – סביבות עבודה כמו Laravel, Slim, Zend Framework, Symphony ועוד רבות וטובות מתבססות עליו ואי אפשר להאשים אותן – נכון להים ניתן למצוא קרוב ל – 137,000 חבילות במאגר!
מה הכוונה ב"ניהול תלויות"?
בהינתן פרוייקט שבו נעשה שימוש במספר ספריות, שעושות בעצמן שימוש בספריות אחרות, Composer מתקין את כל הספריות שנדרשות לפרוייקט על-פי הגדרת המשתמש.
Composer מאפשר להתקין חבילות, כשחבילה יכולה להיות ספריה, פרוייקט, מטא, תוסף או סוג מותאם-אישית; אבל זה נושא מתקדם יותר שארחיב עליו במאמר נפרד,
לסקרנים מחכה מידע נוסף (באנגלית) כאן. במאמר הזה אתייחס לחבילות מסוג ספרייה: ספרייה מכילה אוסף של מחלקות. עוד על זה בהמשך 🙂
בקיצור – אם עוד לא התחלתם, זה הזמן המושלם להתקדם ל – Composer! נצא לדרך?
דרישות מערכת
Composer רץ על PHP ולכן הדרישה המינימלית ביותר היא גרסה PHP 5.3.2 ומעלה.
הכלי רץ באופן זהה על Windows, לינוקס ו – OSX.
במקרים מסויימים, ייתכן שתידרשו להתקין מערכות ניהול גרסאות (Git, Svn וכו') כדי להתקין חבילה, בהתאם לדרך שבה ניהול הגרסאות של החבילה נעשה.
דרישות מכם
אף-על-פי ש – Composer רץ על PHP 5.3.2 ומעלה, המדריך נכתב ל – PHP 7.
בנוסף, עליכם להכיר:
- PHP Namespacing
- JSON
איך להתקין Composer ב – Windows
שלב א' – PHP במסוף
אם כבר התקנתם PHP במסוף, אתם יכולים לדלג לשלב הבא.
לא יודעים אם התקנתם? היכנסו למסוף (Command Prompt) והריצו את הפקודה הבאה:
php -v
אם גרסת ה – PHP שמותקנת הודפסה, מזל טוב! אתם יכולים לדלג על שלב א' ולעבור היישר לשלב ב'.
קיבלתם הודעת שגיאה? אל ייאוש! המשיכו לביצוע שלב א' ולפני שתשימו לב, גם אתם תוכלו להריץ PHP במסוף.
חשוב לי להתעכב על השלב הזה אף-על-פי שהוא לא חובה בשביל להתקין Composer, כי הרצת PHP במסוף היא דרך מהירה ונכונה לבצע בדיקות והרצות של סקריפטים,
ואין סיבה שלא תהפכו את האפשרות הזו לזמינה עבורכם. ההתקנה ממש פשוטה – בואו נעשה את זה 🙂
קודם כל, עלינו לאתר את התיקייה שבה PHP מותקנת.
אם אתם לא יודעים, הדרך הפשוטה ביותר היא ליצור קובץ (השם לא משנה) בשרת המקומי שיכיל:
1 |
<?php phpinfo(); ?> |
כעת, הריצו את הקובץ בדפדפן וחפשו את המחרוזת הבאה: Loaded Configuration File
:
העתיקו את הנתיב ללא php.ini
.
כשאתם מחומשים בנתיב התקנת ה – PHP, היכנסו ללוח הבקרה (Control Panel) > מערכת (System) > הגדרות מערכת מתקדמות (Advanced system settings) > משתני סביבה (Environment Variables):
החלון שנפתח מציגים בפניכם את כל משתני הסביבה של המערכת, מחולקים למשתני סביבה ספציפיים למשתמש ומשתני סביבה גלובליים.
אם אתם מעוניינים להתקין PHP במסוף רק עבור המשתמש הספציפי איתו אתם מחוברים, חפשו את המשנה Path
בחלק העליון:
אם אתם מעוניינים להתקין PHP במסוף עבור כל המשתמשים, חפשו את המשתנה Path בחלק התחתון:
סמנו את המשתנה ולחצו על עריכה (Edit) ובמסך שנפתח, לחצו על הכפתור "חדש" (New) והדביקו את נתיב ההתקנה של PHP:
כמאמר השיר של סטטיק ובנאל תבורי – לחצו OK OK OK ו… שימו PHP!
בחלק ממערכות ההפעלה תצטרכו לבצע הפעלה מחדש בטרם השינויים יכנסו לתוקף ובכל מקרה עליכם לפתוח חלון מסוף חדש.
הקלידו בו את הפקודה מתחילת השלב:
php -v
ועכשיו, אתם אמורים לראות מול עיניכם את גרסת ה – PHP שמותקנת על מחשבכם. בשעה טובה ומוצלחת – יש PHP במסוף!
שלב ב' – התקנת Composer
התקנה באמצעות אשף
הדרך הפשוטה ביותר היא להוריד את קובץ ההתקנה כאן ולהתקין באמצעות ממשק התקנה ווינדוסי-טיפוסי.
ההתקנה מבצעת עבורכם שתי פעולות:
- מתקינה את הכלי
- מוסיפה אותו ל – PATH ככה שתוכלו להשתמש בו גלובלית
יש לסגור את המסוף ולפתוח אותו מחדש בסיום ההתקנה.
סיימתם? אתם יכולים לעבור למדריך!
התקנה ידנית
אפשרות נוספת היא להתקין באופן ידני את הכלי.
כדי לבצע התקנה ידנית, עליכם לבצע את שלב א' (התקנת PHP במסוף).
האפשרות הראשונה עדיפה עבור רוב המשתמשים, במיוחד אם אין לכם ידע בסיסי במשתני מערכת ושימוש במסוף.
פתחו את המסוף ונווטו לתיקייה שבה תרצו להתקין את הכלי, לדוגמה בנתיב הבא:
C:\bin
והכניסו את ארבע הפקודות הבאות (לפי הסדר):
1 2 3 4 |
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');" |
הסבר קצר לגבי הפקודות:
- מורידה את סקריפט ההתקנה של הכלי
- מאמתת את קובץ ההתקנה
- מריצה את קובץ ההתקנה ומורידה את הקובץ composer.phar
- מוחקת את קובץ ההתקנה (
composer-setup.php
)
כעת צרו קובץ composer.bat
באמצעות הרצת השורה הבאה:
C:\bin>echo @php "%~dp0composer.phar" %*>composer.bat
עכשיו חזרו על שלב א', רק שבמקום להוסיף את ההתקנה של PHP ל – PATH, הוסיפו את ההתקנה של Composer.
לא משנה באיזו דרך בחרתם, אם הגעתם עד הלום – הכלי אמור להיות זמין לשימוש. בואו נבדוק:
הריצו במסוף את הפקודה הבאה, שמדפיסה את הגרסה המותקנת:
composer -V
אם מוצגת למול עיניכם גרסת ה – Composer שברשותכם, טפחו לעצמכם קלות על השכם – שרדתם את התקנת הכלי! כפיים!
מדריך התקנה ב – Linux / Unix / OSX
שלב א' – התקנת Composer
הריצו את ארבע הפקודות הבאות במסוף:
1 2 3 4 |
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');" |
הסבר על הפקודות אפשר לקבל בשלב ב' של מדריך ההתקנה למשתמשי ווינדוס.
בקצרה – הפקודות מריצות סקריפט התקנה שמוריד קובץ בשם composer.phar
.
שלב ב' – הזזת composer.phar
ל PATH
עכשיו אנחנו רוצים להזיז את הקובץ הזה לתיקייה שנמצאת בנתיב המערכת (PATH). לשם כך נריץ את הפקודה הבאה:
mv composer.phar /usr/local/bin/composer
- אם התקבלה שגיאת הרשאות, השתמשו ב
sudo
- אם התיקייה
/usr
לא קיימת, צרו אותה:
mkdir -p /usr/local/bin
- איך לשנות את ה – PATH
כמובן שאתם יכולים למקם את הקובץ בכל תיקייה שהיא, כל עוד התיקייה נמצאת בנתיב המערכת.
כדי לבדוק האם צלחתם את ההתקנה, הריצו במסוף את הפקודה הבאה:
composer -V
אם מוצגת למול עיניכם גרסת ה – Composer שברשותכם, דעו שהצלחתם ?
מוכנים? בואו נלחין קצת PHP עם Composer!
ממש תכף, נבנה פרוייקט קטנטן שעושה שימוש בכלי, אבל לפני שאנחנו מריצים שורות, אני רוצה ללמד אתכם את הבסיס:
composer.json
כאמור, Composer הוא כלי לניהול תלויות בפרוייקט.
כשנרצה להשתמש בכלי בפרוייקט מסויים, ניצור קובץ composer.json
בתיקייה הראשית של הפרוייקט.
composer.json
הוא קובץ ההגדרות שלפיו הכלי פועל ועבור כל פרוייקט ניצור קובץ הגדרות חדש.
שימו לב ש – JSON, בניגוד ל – PHP, רגיש לפסיקים מיותרים וסוגי נתונים לא נכונים (אם JSON יצפה לערך בוליאני ונזין "true"
, נקבל שגיאה).
כל קובץ composer.json
יכיל עצם אחד בלבד שיתאר את הפרוייקט:
1 |
{} |
המידע היחיד שאנחנו חייבים להעביר לעצם הוא רשימת החבילות שהפרוייקט דורש, או אם להשתמש במינוח נכון יותר: רשימת התלויות של הפרוייקט, באמצעות התכונה require
:
1 2 3 4 5 |
{ "require": { } } |
כמו שאתם יכולים לראות, require
היא עצם שבתוכו נפרט על התלויות של הפרוייקט:
1 2 3 4 5 |
{ "require": { "vendor-name/package-name": "version" } } |
שם התכונה (vendor-name/package-name
) מכיל את החבילה שבה אנחנו רוצים להשתמש וערך התכונה מכיל הגבלות גרסה.
שימו לב שכדי לייבא חבילה, עלינו "לגלות" ל – Composer גם מי הוא המפיץ (vendor) וגם מה שם החבילה (package-name).
מעבר לרשימת התלויות (require
), יש עוד הרבה מאד מידע שאפשר להעביר לעצם, כמו תלויות לפיתוח (require-dev
), טעינה אוטומטית (autoload
) ועודהגדרות שעליהן ארחיב במאמר נפרד.
* בסוף המדריך רשמתי CHEATSHEET עם מספר פקודות-מסוף נפוצות, כולל פקודה לייבוא חבילה.
חבילה? על שום מה ולמה?
חבילה (package) מאגדת תחתיה קוד PHP לשימוש חוזר.
חבילה יכולה להכיל מספר רב של מחלקות, אבל יכולה להכיל מצד שני רק ממשק אחד, אין באמת תנאי סף ליצירת חבילה, כל עוד היא משיגה את המטרה שלשמה היא נבנתה.
כל חבילה היא פרוייקט Composer ומכילה קובץ composer.json
ובו רשימת תלויות לצד מידע נוסף: שם החבילה, יוצר, גרסה, תלויות ועוד.
כאמור, יש ארבעה סוגי חבילות:
ספריה
ברירת מחדל.
כאשר דורשים חבילה מסוג ספריה, כל קבצי החבילה מועתקים לפרוייקט קיים.
פרוייקט
חבילה שיוצרת פרוייקט חדש.
דוגמה לחבילות כאלה: Symphony, SilverStripe, Laravel ועוד
מטא
חבילה ריקה שמכילה רשימת תלויות.
פלאגין
חבילה שמספקת אשף התקנה לחבילה עם סוג מותאם אישית
Composer מאפשר לנו ליצור גם סוג חבילה מותאם-אישית, אבל זה כבר נושא למתקדמים.
בכל מקרה חשוב שתדעו שלפחות במאמר הזה, נתמקד בסוג הראשון – ספריה בלבד.
ALRIGHT! עברנו על כל המידע שצריך כדי להתחיל להשתמש ב – Composer. אבל רגע, מאיפה בעצם החבילות האלה מגיעות?!
Packagist: מאגר חבילות PHP
Packagist הוא מאגר חבילות PHP ל – Composer.
אלא אם הוגדר אחרת, כשנייבא חבילה לפרוייקט היא תגיע מ – Packagist.
כל אחד יכול לשלוח חבילות למאגר ופה טמון הכוח שבו – 136,965 חבילות (נכון לכתיבת המאמר, ככל הנראה בפועל המספר גבוה יותר) וסדר גודל של 12 מיליון חבילות מותקנות בחודש הופכים אותו למאגר החבילות הפופולרי ביותר, אבל לא היחיד: כל אחד יכול להקים מאגר פרטי / ציבורי של חבילות, אבל זה כבר נושא מתקדם שאני מבטיח לכתוב עליו!
האתר עצמו מכיל מנוע חיפוש שבאמצעותו אתם יכולים לחפש חבילות. נשתמש במאגר בשביל הפרוייקט הלימודי שלנו.
PasswordApi
PasswordAPI
הינו ממשק קטנטן שמאפשר לחולל סיסמאות ומחזיר אותן באחד ממבני הנתונים הבאים: JSON
, XML
או טקסט רגיל.
ישנם שני סוגי סיסמה:
- לא-קריאה: מורכבת מרצף תווים חסר משמעות
- קריאה: מורכבת ממילים
עבור סיסמה לא-קריאה, המשתמש יכול להחליט:
- מה יהיה אורך הסיסמה
- האם תכיל תווים מיוחדים
- האם תכיל אותיות קטנות
- האם תכיל אותיות גדולות
- האם תכיל מספרים
עבור סיסמה קריאה, המשתמש יכול להחליט:
- מה יהיה אורך הסיסמה
בנוסף, המשתמש יכול לקבוע כמה סיסמאות הוא רוצה לחולל וכמובן באיזה פורמט הוא מעוניין לקבל אותן.
לפני שאני מתחיל לפתח, אני אוהב לרשום בצורה מסודרת בדיוק מה אני צריך לעשות:
computer
מחוללת סיסמה לא-קריאה.
- שיטת בקשה: GET
- נתיב:
/computer
- פרמטרים:
- passwordLength (מספר, ברירת מחדל:
8
) - specialChars (בוליאני, ברירת מחדל:
false
) - lowerCase (בוליאני, ברירת מחדל:
true
) - upperCase (בוליאני, ברירת מחדל:
true
) - numbers (בוליאני, ברירת מחדל:
true
) - count (בוליאני, ברירת מחדל:
1
) - returnType (מחרוזת, ברירת מחדל:
JSON
, אפשרויות:JSON
,XML
,TEXT
)
- passwordLength (מספר, ברירת מחדל:
human
מחוללת סיסמה קריאה.
- שיטת בקשה: GET
- נתיב:
/human
- פרמטרים:
- passwordLength (מספר, ברירת מחדל:
13
) - count (מספר, ברירת מחדל:
1
) - returnType (מחרוזת, ברירת מחדל:
JSON
, אפשרויות:JSON
,XML
,TEXT
)
- passwordLength (מספר, ברירת מחדל:
כמו שאתם שמים לב, הממשק מאד פשוט ומכיל רק שתי קריאות אפשריות.
נפתח תיקייה חדשה עבור הפרוייקט בשרת המקומי שתכיל, כרגע, רק את הקובץ composer.json
.
בתוך הקובץ ניצור עצם JSON ריק: {}
.
הממשק שאנחנו בונים צריך לחולל סיסמאות רנדומליות. במקום לכתוב בעצמנו מחלקה שתעשה את זה, בואו נבדוק אם יש חבילה שיכולה לעשות את העבודה השחורה בשבילנו:
ניגש ל – Packagist.org ונחפש את המחרוזת password
אתרו את החבילה hackzilla/password-generator
ולחצו עליה כדי לפתוח את מסך החבילה שמכיל מידע על החבילה: שם, תיאור, גרסאות ותלויות;
בואו נתעכב על התלויות:
בתחילת המדריך הסברתי ש – Composer הוא כלי לניהול תלויות בפרוייקט.
כל חבילה נחשבת לפרוייקט כלומר – כל חבילה מכילה קובץ composer.json
רשימת תלויות לצד פרטים נוספים (שם החבילה, מי עומד מאחוריה, גרסה ועוד)
החבילה hackzilla/password-generator
למשל, תלויה רק בגרסה 5.3.2 ומעלה של PHP.
ממש תכף נסתכל על חבילה שתלויה בחבילות אחרות.
בקובץ composer.json
, נוסיף את התכונה require
ובתוכה את החבילה:
1 2 3 4 5 |
{ "require": { "hackzilla/password-generator": "1.3.*" } } |
ככל הנראה, אתם שואלים את עצמכם שתי שאלות כרגע:
איך אני אמור לדעת להשתמש בחבילות?
בכל דף חבילה תוכלו לגלול ולמצוא בתחתית העמוד הסבר שימוש.
בנוסף, בתפריט הצד יש קישור לעמוד החבילה ב – GitHub, שם לרוב ניתן למצוא תיעוד מלא, אם כי לעיתים לא-כל-כך נדירות תמצאו שחבילה חסרה תיעוד איכותי.
למה, למען השם, יש כוכבית בגרסת החבילה?!
שאלה מעולה! 🙂
Composer מאפשר לנו לכתוב מגבלות גרסה או במילים פשוטות יותר: חוקים שידריכו אותו איזו גרסה להוריד.
ישנן ארבע מגבלות בסיסיות:
גרסה מדוייקת
נגדיר את הגרסה המדוייקת בה נרצה להשתמש:
1 2 3 4 5 |
{ "require": { "vendor/package": "1.0.0" } } |
טווח לוגי
נגדיר טווח גרסאות באמצעות אופרטורים:
1 2 3 4 5 |
{ "require": { "vendor/package": ">=1.0" } } |
גם קשרים לוגיים באים בחשבון:
- או (OR):
||
- וגם (AND):
,
(פסיק)
1 2 3 4 5 |
{ "require": { "vendor/package": ">=1.0 < 1.2" } } |
1 2 3 4 5 |
{ "require": { "vendor/package": "> 1.0,<1.3 || <= 1.5" } } |
טווח רגיל
אפשר גם להגדיר טווח עם מקף -
:
1 2 3 4 5 |
{ "require": { "vendor/package": "1.0 - 2.0" } } |
Wildcard
נוכל להגדיר תבנית גרסה.
למשל, אם נרצה להשתמש בגרסה הכי חדשה של החבילה, אבל להישאר בדומיין של גרסה 2.0, נשתמש באופרטור *
:
1 2 3 4 5 |
{ "require": { "vendor/package": "2.0.*" } } |
טילדה
למי שלא יודע, הסימן ~
נקרא בעברית.. טילדה!
השימוש העיקרי בטילדה הוא לחבילות שאוכפות גרסאות סמנטיות, ככה שאם אין לכם מושג על מה מדובר, יהיה לכם קשה להבין מה הכוונה ולמה הטילדה קיימת.
נשתמש בו כדי להגדיר מהי גרסת המינימום בה אנחנו מוכנים להשתמש ובו זמנית להגדיר שאנחנו רוצים להישאר בדומיין של הגרסה המשנית (המספר השני). מה הכוונה? אסביר באמצעות דוגמה:
1 2 3 4 5 |
{ "require": { "vendor/package": "~3.1.1" } } |
יכולנו להשיג אותה תוצאה על-ידי שימוש בטווח לוגי: >=3.1.0 <3.2.0
קארט
קארט ^
דומה מאד בהתנהגות שלו לטילדה, אבל גמיש יותר: הוא מורה לסקריפט ההתקנה להישאר בדומיין של הגרסה הראשית, אך מאפשר לו להוריד גרסה משנית גבוהה יותר:
1 2 3 4 5 |
{ "require": { "vendor/package": "^2.2.3" } } |
הגמישות של הקארט מתאימה יותר לגרסה 2.0.0 של גרסאות סמנטיות והשימוש בו רווח יותר מאשר בטילדה.
הגבלות נוספות
מעבר לשש ההגבלות שציינתי, יש עוד מספר דרכים בהן ניתן להגביל את גרסת החבילה.
בחזרה לממשק:
מצאנו את החבילה שתחולל עבורנו סיסמאות בקלות ובנוחות. השלב הבא הוא לקבל בקשות ולהחזיר תשובות – כלומר לבנות ראוטר.
בשביל המדריך אשתמש ב – Slim Framework, סביבת פיתוח קלה להתמודדות עם הודעות HTTP.
אתרו את החבילה במנוע החיפוש של packagist; שימו לב שבניגוד לחבילה הראשונה, Slim כן תלויה בחבילות נוספות:
האם זה אומר שעלינו לציין את כל החבילות האלה בקובץ ההגדרות שלנו? תכף נגלה:
כמו שעשינו עם hackzilla/password-generator
, נוסיף גם את החבילה הזו לרשימת התלויות שלנו בקובץ composer.json
:
1 2 3 4 5 6 |
{ "require": { "hackzilla/password-generator": "1.3.*", "slim/slim": "~3.8.1" } } |
התקנת החבילות
פתחו את המסוף, נווטו לתיקיית הפרוייקט והריצו את הפקודה הבאה:
composer install
וכאן הקסם מתחיל לקרות: הפקודה install
מתקינה את כל התלויות של הפרוייקט:
הכלי יודע להתקין את כל התלויות, גם אלה של החבילות, מבלי שנצטרך לציין אותן מפורשות. דיי מגניב, לא?
אם תציצו בתיקיית הפרוייקט, תוכלו לראות שנוספה תיקייה חדשה בשם vendor
שמכילה את כל התלויות של הפרוייקט לצד קובץ autoload.php
.
איך להשתמש בחבילות
צרו קובץ חדש בשם index.php
בתיקיה הראשית של הפרוייקט.
חשוב לי להבהיר, שבעולם האמיתי ככל הנראה לא היינו בונים ממשק בצורה כזו – בקובץ אחד בו הכל מרוכז; בשביל שהדברים יהיו פשוטים וקלים לביצוע ככל האפשר, במדריך הזה כן נרכז את הקוד תחת index.php
.
כדי להשתמש בחבילות עלינו לטעון את הקובץ autoload.php
שנמצא בתיקייה vendor
:
1 2 3 |
<?php require('./vendor/autoload.php'); |
הקובץ הזה מבצע טעינה אוטומטית של כל החבילות שבהן נעשה שימוש בפרוייקט.
במאמר הזה אני לא אסביר איך מתבצעת טעינה אוטומטית, אבל אם אין לכם סבלנות לחכות שאכתוב על כך (ואני אכתוב), אתם יכולים לקרוא על טעינה אוטומטית ב – Composer כאן.
עכשיו כשכל החבילות זמינות לשימוש, בואו נכתוב קצת PHP איתן, כדי שתדעו שאני לא עובד עליכם!
מחולל הסיסמה יעבוד לפי ארבעת השלבים הבאים:
- מתקבלת בקשת
GET
לסיסמה לא-קריאה (/computer
) או לסיסמה קריאה (/human
) - נעשית בדיקה האם התקבלו פרמטרים שונים מברירת המחדל
- יצירת הסיסמאות
- הסיסמאות מוחזרות בפורמט המתאים
'תפיסת' בקשות GET
מתאימות (סיסמה קריאה / לא קריאה)
1 2 3 4 5 |
<?php require('./vendor/autoload.php'); $app = new \Slim\App; |
ונגדיר את הראוטר שלנו על-פי טבלת הפעולות הזמינות:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php require('./vendor/autoload.php'); $app = new \Slim\App; $app->get('/computer', function($request, $response, $args) { }); $app->get('/human', function($request, $response, $args) { }); |
הפונקציה get
מקבלת שני פרמטרים:
- נתיב
- פונקציה שתבוצע כאשר התקבלה בקשת
GET
לנתיב שצוין
גם הפונקציה האנונימית שתבוצע בעת בקשת GET
מתאימה מקבלת שלושה פרמטרים:
- מופע שמתאר את בקשת ה – HTTP שהתקבלה
- מופע שמתאר את התשובה שנחזיר
- ארגומנטים שהתקבלו עם הבקשה
השוואת פרמטרים לברירת המחדל
בשלב השני נגדיר פונקציית עזר שמשווה בין ברירת המחדל לפרמטרים שהתקבלו:
1 2 3 4 5 6 7 8 |
function compareSettings($settings, $args) { foreach($args as $key => $val) { if(isset($settings[$key]) && $val != $settings[$key]) $settings[$key] = $val; } return $settings; } |
יצירת הסיסמאות
אם נסתכל בתיעוד של hackzilla/password-generator
נוכל למצוא שתי מחלקות שמתאימות בדיוק למה שאנחנו צריכים: computerPasswordGenerator
ו – humanPasswordGenerator
.
computerPasswordGenerator
ישמש אותנו ליצירת סיסמה חסרת-משמעות:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$app->get('/computer', function($request, $response, $args) { $generator = new Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator; $defaults = [ 'passwordLength' => 13, 'specialChars' => false, 'lowerCase' => true, 'upperCase' => true, 'numbers' => true, 'count' => 1, 'returnType' => 'JSON' ]; $config = compareSettings($defaults, $request->getQueryParams()); $generator ->setLength((int)$config['passwordLength']) ->setSymbols((bool)$config['specialChars']) ->setLowercase((bool)$config['lowerCase']) ->setUppercase((bool)$config['upperCase']) ->setNumbers((bool)$config['numbers']); $passwords = $generator->generatePasswords((int)$config['count']); }); |
$request->getQueryParams()
מחזירה מערך של פרמטרי Query string
humanPasswordGenerator
ישמש אותנו ליצירת סיסמה שמורכבת ממילים:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$app->get('/human', function($request, $response, $args) { $generator = new Hackzilla\PasswordGenerator\Generator\HumanPasswordGenerator; $defaults = [ 'passwordLength' => 12, 'count' => 1 ]; $config = compareSettings($defaults, $request->getQueryParams()); $generator ->SetWordList('./words.txt') ->setWordSeparator(''); ->setLength((int)$config['passwordLength']); $passwords = $generator->generatePasswords((int)$config['count']); }); |
לצערי, התיעוד של החבילה hackzilla/password-generator
לוקה בחסר, מה שעלול לקרות מידי פעם.
במקרים כאלה יש לנו שתי אפשרויות:
- GOOGLE IT
- להיכנס לקבצי המקור ולהבין מה קורה שם
בשביל לחולל סיסמה שמורכבת ממילים, אנחנו צריכים ליצור קובץ אוצר מילים.
כדי להבין איך הקובץ, שאותו נעביר לפונקציה setWordList
צריך להראות, נכנסתי לקבצי המקור וגיליתי שכל מילה צריכה להתחיל בשורה חדשה.
אתם יכולים או ליצור בעצמכם קובץ מילים, או להוריד אחד כזה כאן; בכל מקרה את הקובץ מקמו בתיקייה הראשית של הפרוייקט.
החזרת הסיסמאות במבנה הנתונים המתאים
הדבר האחרון שנשאר לנו לעשות הוא להחזיר את הסיסמאות בפורמט המתאים – כלומר JSON
או XML
או TEXT
.
הממ.. למישהו יש רעיון איך נעשה את זה? אפשר לכתוב מחלקה שתעשה את זה בשבילנו, אבל למה אנחנו לומדים Composer? בואו נחפש חבילה כזאת 🙂
אחרי חיפוש קצר, מצאתי את החבילה jms/serializer
שבצירוף מקרים מדהים תומכת בשלושת סוגי הנתונים שהממשק שלנו מחזיר!
הוסיפו את החבילה לקובץ ההגדרות:
1 2 3 4 5 6 7 |
{ "require": { "hackzilla/password-generator": "1.3.0", "slim/slim": "~3.8.1", "jms/serializer": "^1.6.2" } } |
והריצו את הפקודה: composer install
אם מילאתם אחר הוראות המדריך כראוי, קיבלתם את ההודעה הבאה:
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Nothing to install or update
Generating autoload files
ההודעה הזו נותנת לנו שלוש פיסות אינפורמציה:
- בניגוד לפעם הקודמת בה הרצנו את הפקודה
composer install
, הפעם הכלי מתקין את התלויות שנמצאות ב'lock file' - אזהרה שה – 'lock file' שלנו לא מעודכן!
- יש להריץ את הפקודה
update
אבל רגע, מה זה בכלל ה – 'lock file' הזה?
composer.lock
את התלויות של הפרוייקט ומידע נוסף אנחנו מגדירים בקובץ composer.json
. כאשר אנחנו קוראים לפקודה composer install
בפעם הראשונה, נוצר קובץ נוסף שאולי שמתם לב אליו בשם composer.lock
שהוא בעצם ה – 'lock file' המפורסם מהפסקה הקודמת.
קובץ המנעול 'נועל' את האפליקציה למצב מסויים ומציין באופן מפורש את החבילות בהן נעשה שימוש כולל גרסה מלאה, מקור ועוד.
אם ב – composer.json
, נכתוב:
1 2 3 4 5 |
{ "require": { "package/vendor": "1.0.*" } } |
והגרסה המתאימה ביותר נכון לרגע שבו התקנו את החבילות (כלומר הרצנו את הפקודה composer install
) היא 1.0.7
, בקובץ המנעול יצויין שאנחנו משתמשים בחבילה בגרסה 1.0.7
:
1 2 3 4 5 6 7 8 9 10 11 12 |
{ ... "packages": [ { "name": "vendor/name", "version": "1.0.7", ... } ... ] ... } |
אפשר להגיד שקובץ המנעול מתאר את מצב הפרוייקט בפועל, והוא דואג שכשתתקינו חבילה או פרוייקט, ייעשה שימוש במרכיבים הנכונים ובגרסאות הנכונות שבהם נעשה שימוש במהלך הפיתוח.
חפרת.. מה אני עושה עכשיו?
כשאנחנו מעוניינים לעדכן את התלויות של הפרוייקט, נשתמש בפקודה composer update
, שבפועל עושה את הפעולות הבאות:
- קוראת את הקובץ
composer.json
- מתקינה את החבילות שנדרשו בגרסאות המתאימות
- כותבת קובץ
composer.lock
חדש כדי שישקף את מצב הפרוייקט לאחר העדכון - מחוללת קבצי טעינה אוטומטית
חשוב להבין שהפעולה composer install
בודקת האם הקובץ composer.lock
קיים:
- אם לא: מבצעת את הפעולה
composer update
- אם כן: מתקינה את החבילות הנדרשות לפי הקובץ
composer.lock
- מחוללת קבצי טעינה אוטומטית
ובכן, למה אתם מחכים? הריצו את הפקודה composer update
והחבילה החדשה שלנו תותקן ונוכל לסיים את הממשק שלנו.
שימו לב שהפקודה מבצעת עדכון ומתקינה רק חבילות חדשות / חבילות עם גרסה חדשה יותר, בהתאם להגבלות.
נוסיף מתחת לפונקציה compareSettings
שלוש פעולות עזר שחוזרות על עצמן בין אם המשתמש בחר בסיסמה לא קריאה ובין אם בחר בסיסמה קריאה:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
function serializePasswords($passwords, $type) { $type = strtolower($type); $serializer = JMS\Serializer\SerializerBuilder::create()->build(); if($type == "text") return implode("\n", $passwords); if(!in_array($type, ["json", "xml"])) $type = "json"; return $serializer->serialize($passwords, $type); } function getHeaderContentType($type) { $type = strtolower($type); if($type == "xml") return "text/xml"; if($type == "text") return "text/plain"; return "application/json"; } function generateResponse($response, $passwords, $returnType) { // Response body $body = $response->getBody(); $body->write(serializePasswords($passwords, $returnType)); // Create new response with appropriate header $newResponse = $response->withHeader('Content-type', getHeaderContentType($returnType)); return $newResponse->withBody($body); } |
serializePasswords
משתמשת בחבילה שזה עתה ייבאנו,jms/serializer
כדי להפוך את המערך שלנו לטיפוס הנתונים המתאיםgetHeaderContentType
מחזירה את סוג הנתונים שנשלח ב – Header של התגובהgenerateResponse
מייצרת תגובה חדשה עם הנתונים שהתקבלו משתי הפונקציות למעלה
כל שנותר לנו לעשות הוא לקרוא לפונקציה generateResponse
בפונקציות האנונימיות שלנו, ונקבל את הקוד המלא של הממשק:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
<?php require('./vendor/autoload.php'); $app = new \Slim\App(); function compareSettings($settings, $args) { foreach($args as $key => $val) { if(isset($settings[$key]) && $val != $settings[$key]) $settings[$key] = $val; } return $settings; } function serializePasswords($passwords, $type) { $type = strtolower($type); $serializer = JMS\Serializer\SerializerBuilder::create()->build(); if($type == "text") return implode("\n", $passwords); if(!in_array($type, ["json", "xml"])) $type = "json"; return $serializer->serialize($passwords, $type); } function getHeaderContentType($type) { $type = strtolower($type); if($type == "xml") return "text/xml"; if($type == "text") return "text/plain"; return "application/json"; } function generateResponse($response, $passwords, $returnType) { // Response body $body = $response->getBody(); $body->write(serializePasswords($passwords, $returnType)); // Create new response with appropriate header $newResponse = $response->withHeader('Content-type', getHeaderContentType($returnType)); return $newResponse->withBody($body); } $app->get('/computer', function($request, $response, $args) { $generator = new Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator; $defaults = [ 'passwordLength' => 8, 'specialChars' => false, 'lowerCase' => true, 'upperCase' => true, 'numbers' => true, 'count' => 1, 'returnType' => 'json' ]; $config = compareSettings($defaults, $request->getQueryParams()); $generator ->setLength((int)$config['passwordLength']) ->setSymbols((bool)$config['specialChars']) ->setLowercase((bool)$config['lowerCase']) ->setUppercase((bool)$config['upperCase']) ->setNumbers((bool)$config['numbers']); $passwords = $generator->generatePasswords((int)$config['count']); return generateResponse($response, $passwords, $config['returnType']); }); $app->get('/human', function($request, $response, $args) { $generator = new Hackzilla\PasswordGenerator\Generator\HumanPasswordGenerator; $defaults = [ 'passwordLength' => 12, 'count' => 1, 'returnType' => 'json' ]; $config = compareSettings($defaults, $request->getQueryParams()); $generator ->SetWordList('./words.txt') ->setWordSeparator('') ->setLength((int)$config['passwordLength']); $passwords = $generator->generatePasswords((int)$config['count']); return generateResponse($response, $passwords, $config['returnType']); }); $app->run(); |
הפעולה $app->run()
מפעילה את הראוטר.
וזהו זה! יש לנו ממשק מחולל סיסמאות לתפארת!
כעת תוכלו לגלוש בדפדפן לשרת המקומי ולבחון את הממשק שזה עתה בנינו.
כמובן שתצטרכו לגשת לנתיב הרצוי עם הפרמטרים, לדוגמה:
http://localhost/passwordApi/index.php/human?passwordLength=20&count=5
בונוס: להקים שרת מקומי עם המסוף
אם התקנתם PHP במסוף כפי שהמלצתי, אתם יכולים להקליד את השורה הבאה, מתוך תיקיית הפרוייקט:
php -S localhost:8000
ושרת חדש יקום בכתובת http://localhost:8000
ואז תוכלו לבצע את הבדיקות בשרת מבודד:
http://localhost:8000/index.php/human?passwordLength=20&count=5
CHEATSHEET: פקודות נפוצות למסוף
הכלי, כאמור, רץ במסוף. כ-כזה, הוא מכיל מספר גדול של פקודות, בחלקן תשתמשו באופן יום-יומי, בחלקן לעיתים נדירות.
אם רמת ההיכרות הנוכחית שלכם עם הכלי מבוססת על המדריך הזה, יש 4 פקודות ששווה שתכירו:
install
composer install
מתקינה את תלויות הפרוייקט לפי הקובץ composer.lock
או composer.json
, אם הראשון לא קיים מבצעת את הפקודה update
update
composer update
מתקינה את תלויות הפרוייקט לפי הקובץ composer.json
וכותבת קובץ composer.lock
חדש
require
composer require vendor/package:version
מוסיפה לקובץ composer.json
את החבילה שצוינה ומריצה את הפקודה composer install/update
remove
composer remove vendor/package
מוחקת מקובץ composer.json את החבילה שצוינה ומריצה את הפקודה composer update
זה לא הסוף..
תנו לעצמכם טפיחה על השכם: התמדתם והגעתם לסוף המאמר – ריספקט.
אני מקווה שהצלחתי ללמד אתכם את המהות של Composer ואיך להשתמש בו.
אבל אל תיכנסו לאופוריה! עוד יש לנו על מה לעבור ואני מבטיח שאני ארשום מאמר המשך עם נושאים מתקדמים יותר כמו התקנת חבילות גלובלית, טעינה אוטומטית, כתיבת חבילות ועוד.
עד לפעם הבאה 🙂
3 תגובות
יניב
26 באפריל 2017 - 0:47תודה על המדריך המושקע!
חגית
16 בדצמבר 2018 - 15:07מאמר מצוין. תודה רבה!
יהודה
4 ביוני 2019 - 19:58תותח!!