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 במסוף, אתם יכולים לדלג לשלב הבא.
לא יודעים אם התקנתם? היכנסו למסוף (Command Prompt) והריצו את הפקודה הבאה:
php -v
אם גרסת ה – PHP שמותקנת הודפסה, מזל טוב! אתם יכולים לדלג על שלב א' ולעבור היישר לשלב ב'.
קיבלתם הודעת שגיאה? אל ייאוש! המשיכו לביצוע שלב א' ולפני שתשימו לב, גם אתם תוכלו להריץ PHP במסוף.
חשוב לי להתעכב על השלב הזה אף-על-פי שהוא לא חובה בשביל להתקין Composer, כי הרצת PHP במסוף היא דרך מהירה ונכונה לבצע בדיקות והרצות של סקריפטים,
ואין סיבה שלא תהפכו את האפשרות הזו לזמינה עבורכם. ההתקנה ממש פשוטה – בואו נעשה את זה
קודם כל, עלינו לאתר את התיקייה שבה PHP מותקנת.
אם אתם לא יודעים, הדרך הפשוטה ביותר היא ליצור קובץ (השם לא משנה) בשרת המקומי שיכיל:
<?php phpinfo(); ?>
כעת, הריצו את הקובץ בדפדפן וחפשו את המחרוזת הבאה: Loaded Configuration File
:
http://masterscripter.co.il/wp-conten ... s/2017/04/lcf-300x268.jpg 300w" sizes="(max-width: 600px) 100vw, 600px" />
העתיקו את הנתיב ללא php.ini
.
כשאתם מחומשים בנתיב התקנת ה – PHP, היכנסו ללוח הבקרה (Control Panel) > מערכת (System) > הגדרות מערכת מתקדמות (Advanced system settings) > משתני סביבה (Environment Variables):
http://masterscripter.co.il/wp-conten ... ds/2017/04/cp-300x151.jpg 300w" sizes="(max-width: 680px) 100vw, 680px" />
החלון שנפתח מציגים בפניכם את כל משתני הסביבה של המערכת, מחולקים למשתני סביבה ספציפיים למשתמש ומשתני סביבה גלובליים.
אם אתם מעוניינים להתקין PHP במסוף רק עבור המשתמש הספציפי איתו אתם מחוברים, חפשו את המשנה Path
בחלק העליון:
http://masterscripter.co.il/wp-conten ... 7/04/userpath-300x141.jpg 300w" sizes="(max-width: 617px) 100vw, 617px" />
אם אתם מעוניינים להתקין PHP במסוף עבור כל המשתמשים, חפשו את המשתנה Path בחלק התחתון:
http://masterscripter.co.il/wp-conten ... 04/systempath-300x141.jpg 300w" sizes="(max-width: 617px) 100vw, 617px" />
סמנו את המשתנה ולחצו על עריכה (Edit) ובמסך שנפתח, לחצו על הכפתור "חדש" (New) והדביקו את נתיב ההתקנה של PHP:
http://masterscripter.co.il/wp-conten ... ds/2017/04/ev-300x289.jpg 300w" sizes="(max-width: 527px) 100vw, 527px" />
כמאמר השיר של סטטיק ובנאל תבורי – לחצו OK OK OK ו… שימו PHP!
בחלק ממערכות ההפעלה תצטרכו לבצע הפעלה מחדש בטרם השינויים יכנסו לתוקף ובכל מקרה עליכם לפתוח חלון מסוף חדש.
הקלידו בו את הפקודה מתחילת השלב:
php -v
ועכשיו, אתם אמורים לראות מול עיניכם את גרסת ה – PHP שמותקנת על מחשבכם. בשעה טובה ומוצלחת – יש PHP במסוף!
הדרך הפשוטה ביותר היא להוריד את קובץ ההתקנה כאן ולהתקין באמצעות ממשק התקנה ווינדוסי-טיפוסי.
ההתקנה מבצעת עבורכם שתי פעולות:
יש לסגור את המסוף ולפתוח אותו מחדש בסיום ההתקנה.
סיימתם? אתם יכולים לעבור למדריך!
אפשרות נוספת היא להתקין באופן ידני את הכלי.
כדי לבצע התקנה ידנית, עליכם לבצע את שלב א' (התקנת PHP במסוף).
האפשרות הראשונה עדיפה עבור רוב המשתמשים, במיוחד אם אין לכם ידע בסיסי במשתני מערכת ושימוש במסוף.
פתחו את המסוף ונווטו לתיקייה שבה תרצו להתקין את הכלי, לדוגמה בנתיב הבא:
C:\bin
והכניסו את ארבע הפקודות הבאות (לפי הסדר):
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-setup.php
)כעת צרו קובץ composer.bat
באמצעות הרצת השורה הבאה:
C:\bin>echo @php "%~dp0composer.phar" %*>composer.bat
עכשיו חזרו על שלב א', רק שבמקום להוסיף את ההתקנה של PHP ל – PATH, הוסיפו את ההתקנה של Composer.
לא משנה באיזו דרך בחרתם, אם הגעתם עד הלום – הכלי אמור להיות זמין לשימוש. בואו נבדוק:
הריצו במסוף את הפקודה הבאה, שמדפיסה את הגרסה המותקנת:
composer -V
אם מוצגת למול עיניכם גרסת ה – Composer שברשותכם, טפחו לעצמכם קלות על השכם – שרדתם את התקנת הכלי! כפיים!
הריצו את ארבע הפקודות הבאות במסוף:
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
כמובן שאתם יכולים למקם את הקובץ בכל תיקייה שהיא, כל עוד התיקייה נמצאת בנתיב המערכת.
כדי לבדוק האם צלחתם את ההתקנה, הריצו במסוף את הפקודה הבאה:
composer -V
אם מוצגת למול עיניכם גרסת ה – Composer שברשותכם, דעו שהצלחתם
ממש תכף, נבנה פרוייקט קטנטן שעושה שימוש בכלי, אבל לפני שאנחנו מריצים שורות, אני רוצה ללמד אתכם את הבסיס:
כאמור, Composer הוא כלי לניהול תלויות בפרוייקט.
כשנרצה להשתמש בכלי בפרוייקט מסויים, ניצור קובץ composer.json
בתיקייה הראשית של הפרוייקט.
composer.json
הוא קובץ ההגדרות שלפיו הכלי פועל ועבור כל פרוייקט ניצור קובץ הגדרות חדש.
שימו לב ש – JSON, בניגוד ל – PHP, רגיש לפסיקים מיותרים וסוגי נתונים לא נכונים (אם JSON יצפה לערך בוליאני ונזין "true"
, נקבל שגיאה).
כל קובץ composer.json
יכיל עצם אחד בלבד שיתאר את הפרוייקט:
{}
המידע היחיד שאנחנו חייבים להעביר לעצם הוא רשימת החבילות שהפרוייקט דורש, או אם להשתמש במינוח נכון יותר: רשימת התלויות של הפרוייקט, באמצעות התכונה require
:
{
"require": {
}
}
כמו שאתם יכולים לראות, require
היא עצם שבתוכו נפרט על התלויות של הפרוייקט:
{
"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 ל – Composer.
אלא אם הוגדר אחרת, כשנייבא חבילה לפרוייקט היא תגיע מ – Packagist.
כל אחד יכול לשלוח חבילות למאגר ופה טמון הכוח שבו – 136,965 חבילות (נכון לכתיבת המאמר, ככל הנראה בפועל המספר גבוה יותר) וסדר גודל של 12 מיליון חבילות מותקנות בחודש הופכים אותו למאגר החבילות הפופולרי ביותר, אבל לא היחיד: כל אחד יכול להקים מאגר פרטי / ציבורי של חבילות, אבל זה כבר נושא מתקדם שאני מבטיח לכתוב עליו!
האתר עצמו מכיל מנוע חיפוש שבאמצעותו אתם יכולים לחפש חבילות. נשתמש במאגר בשביל הפרוייקט הלימודי שלנו.
PasswordAPI
הינו ממשק קטנטן שמאפשר לחולל סיסמאות ומחזיר אותן באחד ממבני הנתונים הבאים: JSON
, XML
או טקסט רגיל.
ישנם שני סוגי סיסמה:
עבור סיסמה לא-קריאה, המשתמש יכול להחליט:
עבור סיסמה קריאה, המשתמש יכול להחליט:
בנוסף, המשתמש יכול לקבוע כמה סיסמאות הוא רוצה לחולל וכמובן באיזה פורמט הוא מעוניין לקבל אותן.
לפני שאני מתחיל לפתח, אני אוהב לרשום בצורה מסודרת בדיוק מה אני צריך לעשות:
מחוללת סיסמה לא-קריאה.
/computer
8
)false
)true
)true
)true
)1
)JSON
, אפשרויות: JSON
, XML
, TEXT
)מחוללת סיסמה קריאה.
/human
13
)1
)JSON
, אפשרויות: JSON
, XML
, TEXT
)כמו שאתם שמים לב, הממשק מאד פשוט ומכיל רק שתי קריאות אפשריות.
נפתח תיקייה חדשה עבור הפרוייקט בשרת המקומי שתכיל, כרגע, רק את הקובץ composer.json
.
בתוך הקובץ ניצור עצם JSON ריק: {}
.
הממשק שאנחנו בונים צריך לחולל סיסמאות רנדומליות. במקום לכתוב בעצמנו מחלקה שתעשה את זה, בואו נבדוק אם יש חבילה שיכולה לעשות את העבודה השחורה בשבילנו:
ניגש ל – Packagist.org ונחפש את המחרוזת password
אתרו את החבילה hackzilla/password-generator
ולחצו עליה כדי לפתוח את מסך החבילה שמכיל מידע על החבילה: שם, תיאור, גרסאות ותלויות;
בואו נתעכב על התלויות:
בתחילת המדריך הסברתי ש – Composer הוא כלי לניהול תלויות בפרוייקט.
כל חבילה נחשבת לפרוייקט כלומר – כל חבילה מכילה קובץ composer.json
רשימת תלויות לצד פרטים נוספים (שם החבילה, מי עומד מאחוריה, גרסה ועוד)
החבילה hackzilla/password-generator
למשל, תלויה רק בגרסה 5.3.2 ומעלה של PHP.
ממש תכף נסתכל על חבילה שתלויה בחבילות אחרות.
בקובץ composer.json
, נוסיף את התכונה require
ובתוכה את החבילה:
{
"require": {
"hackzilla/password-generator": "1.3.*"
}
}
ככל הנראה, אתם שואלים את עצמכם שתי שאלות כרגע:
בכל דף חבילה תוכלו לגלול ולמצוא בתחתית העמוד הסבר שימוש.
בנוסף, בתפריט הצד יש קישור לעמוד החבילה ב – GitHub, שם לרוב ניתן למצוא תיעוד מלא, אם כי לעיתים לא-כל-כך נדירות תמצאו שחבילה חסרה תיעוד איכותי.
שאלה מעולה!
Composer מאפשר לנו לכתוב מגבלות גרסה או במילים פשוטות יותר: חוקים שידריכו אותו איזו גרסה להוריד.
ישנן ארבע מגבלות בסיסיות:
נגדיר את הגרסה המדוייקת בה נרצה להשתמש:
{
"require": {
"vendor/package": "1.0.0"
}
}
נגדיר טווח גרסאות באמצעות אופרטורים:
{
"require": {
"vendor/package": ">=1.0"
}
}
גם קשרים לוגיים באים בחשבון:
||
(רווח) או ,
(פסיק){
"require": {
"vendor/package": ">=1.0 < 1.2"
}
}
{
"require": {
"vendor/package": "> 1.0,<1.3 || <= 1.5"
}
}
אפשר גם להגדיר טווח עם מקף -
:
{
"require": {
"vendor/package": "1.0 - 2.0"
}
}
נוכל להגדיר תבנית גרסה.
למשל, אם נרצה להשתמש בגרסה הכי חדשה של החבילה, אבל להישאר בדומיין של גרסה 2.0, נשתמש באופרטור *
:
{
"require": {
"vendor/package": "2.0.*"
}
}
למי שלא יודע, הסימן ~
נקרא בעברית.. טילדה!
השימוש העיקרי בטילדה הוא לחבילות שאוכפות גרסאות סמנטיות, ככה שאם אין לכם מושג על מה מדובר, יהיה לכם קשה להבין מה הכוונה ולמה הטילדה קיימת.
נשתמש בו כדי להגדיר מהי גרסת המינימום בה אנחנו מוכנים להשתמש ובו זמנית להגדיר שאנחנו רוצים להישאר בדומיין של הגרסה המשנית (המספר השני). מה הכוונה? אסביר באמצעות דוגמה:
{
"require": {
"vendor/package": "~3.1.1"
}
}
יכולנו להשיג אותה תוצאה על-ידי שימוש בטווח לוגי: >=3.1.0 <3.2.0
קארט ^
דומה מאד בהתנהגות שלו לטילדה, אבל גמיש יותר: הוא מורה לסקריפט ההתקנה להישאר בדומיין של הגרסה הראשית, אך מאפשר לו להוריד גרסה משנית גבוהה יותר:
{
"require": {
"vendor/package": "^2.2.3"
}
}
הגמישות של הקארט מתאימה יותר לגרסה 2.0.0 של גרסאות סמנטיות והשימוש בו רווח יותר מאשר בטילדה.
מעבר לשש ההגבלות שציינתי, יש עוד מספר דרכים בהן ניתן להגביל את גרסת החבילה.
בחזרה לממשק:
מצאנו את החבילה שתחולל עבורנו סיסמאות בקלות ובנוחות. השלב הבא הוא לקבל בקשות ולהחזיר תשובות – כלומר לבנות ראוטר.
בשביל המדריך אשתמש ב – Slim Framework, סביבת פיתוח קלה להתמודדות עם הודעות HTTP.
אתרו את החבילה במנוע החיפוש של packagist; שימו לב שבניגוד לחבילה הראשונה, Slim כן תלויה בחבילות נוספות:
האם זה אומר שעלינו לציין את כל החבילות האלה בקובץ ההגדרות שלנו? תכף נגלה:
כמו שעשינו עם hackzilla/password-generator
, נוסיף גם את החבילה הזו לרשימת התלויות שלנו בקובץ composer.json
:
{
"require": {
"hackzilla/password-generator": "1.3.*",
"slim/slim": "~3.8.1"
}
}
פתחו את המסוף, נווטו לתיקיית הפרוייקט והריצו את הפקודה הבאה:
composer install
וכאן הקסם מתחיל לקרות: הפקודה install
מתקינה את כל התלויות של הפרוייקט:
הכלי יודע להתקין את כל התלויות, גם אלה של החבילות, מבלי שנצטרך לציין אותן מפורשות. דיי מגניב, לא?
אם תציצו בתיקיית הפרוייקט, תוכלו לראות שנוספה תיקייה חדשה בשם vendor
שמכילה את כל התלויות של הפרוייקט לצד קובץ autoload.php
.
צרו קובץ חדש בשם index.php
בתיקיה הראשית של הפרוייקט.
חשוב לי להבהיר, שבעולם האמיתי ככל הנראה לא היינו בונים ממשק בצורה כזו – בקובץ אחד בו הכל מרוכז; בשביל שהדברים יהיו פשוטים וקלים לביצוע ככל האפשר, במדריך הזה כן נרכז את הקוד תחת index.php
.
כדי להשתמש בחבילות עלינו לטעון את הקובץ autoload.php
שנמצא בתיקייה vendor
:
<?php
require('./vendor/autoload.php');
הקובץ הזה מבצע טעינה אוטומטית של כל החבילות שבהן נעשה שימוש בפרוייקט.
במאמר הזה אני לא אסביר איך מתבצעת טעינה אוטומטית, אבל אם אין לכם סבלנות לחכות שאכתוב על כך (ואני אכתוב), אתם יכולים לקרוא על טעינה אוטומטית ב – Composer כאן.
עכשיו כשכל החבילות זמינות לשימוש, בואו נכתוב קצת PHP איתן, כדי שתדעו שאני לא עובד עליכם!
מחולל הסיסמה יעבוד לפי ארבעת השלבים הבאים:
GET
לסיסמה לא-קריאה (/computer
) או לסיסמה קריאה (/human
)GET
מתאימות (סיסמה קריאה / לא קריאה)<?php
require('./vendor/autoload.php');
$app = new \Slim\App;
ונגדיר את הראוטר שלנו על-פי טבלת הפעולות הזמינות:
<?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
מתאימה מקבלת שלושה פרמטרים:
בשלב השני נגדיר פונקציית עזר שמשווה בין ברירת המחדל לפרמטרים שהתקבלו:
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
ישמש אותנו ליצירת סיסמה חסרת-משמעות:
$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 stringhumanPasswordGenerator
ישמש אותנו ליצירת סיסמה שמורכבת ממילים:
$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
לוקה בחסר, מה שעלול לקרות מידי פעם.
במקרים כאלה יש לנו שתי אפשרויות:
בשביל לחולל סיסמה שמורכבת ממילים, אנחנו צריכים ליצור קובץ אוצר מילים.
כדי להבין איך הקובץ, שאותו נעביר לפונקציה setWordList
צריך להראות, נכנסתי לקבצי המקור וגיליתי שכל מילה צריכה להתחיל בשורה חדשה.
אתם יכולים או ליצור בעצמכם קובץ מילים, או להוריד אחד כזה כאן; בכל מקרה את הקובץ מקמו בתיקייה הראשית של הפרוייקט.
הדבר האחרון שנשאר לנו לעשות הוא להחזיר את הסיסמאות בפורמט המתאים – כלומר JSON
או XML
או TEXT
.
הממ.. למישהו יש רעיון איך נעשה את זה? אפשר לכתוב מחלקה שתעשה את זה בשבילנו, אבל למה אנחנו לומדים Composer? בואו נחפש חבילה כזאת
אחרי חיפוש קצר, מצאתי את החבילה jms/serializer
שבצירוף מקרים מדהים תומכת בשלושת סוגי הנתונים שהממשק שלנו מחזיר!
הוסיפו את החבילה לקובץ ההגדרות:
{
"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'update
אבל רגע, מה זה בכלל ה – 'lock file' הזה?
את התלויות של הפרוייקט ומידע נוסף אנחנו מגדירים בקובץ composer.json
. כאשר אנחנו קוראים לפקודה composer install
בפעם הראשונה, נוצר קובץ נוסף שאולי שמתם לב אליו בשם composer.lock
שהוא בעצם ה – 'lock file' המפורסם מהפסקה הקודמת.
קובץ המנעול 'נועל' את האפליקציה למצב מסויים ומציין באופן מפורש את החבילות בהן נעשה שימוש כולל גרסה מלאה, מקור ועוד.
אם ב – composer.json
, נכתוב:
{
"require": {
"package/vendor": "1.0.*"
}
}
והגרסה המתאימה ביותר נכון לרגע שבו התקנו את החבילות (כלומר הרצנו את הפקודה composer install
) היא 1.0.7
, בקובץ המנעול יצויין שאנחנו משתמשים בחבילה בגרסה 1.0.7
:
{
...
"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
שלוש פעולות עזר שחוזרות על עצמן בין אם המשתמש בחר בסיסמה לא קריאה ובין אם בחר בסיסמה קריאה:
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
בפונקציות האנונימיות שלנו, ונקבל את הקוד המלא של הממשק:
<?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.ph ... ordLength=20&count=5
אם התקנתם PHP במסוף כפי שהמלצתי, אתם יכולים להקליד את השורה הבאה, מתוך תיקיית הפרוייקט:
php -S localhost:8000
ושרת חדש יקום בכתובת http://localhost:8000
ואז תוכלו לבצע את הבדיקות בשרת מבודד:
http://localhost:8000/index.php/human ... ordLength=20&count=5
הכלי, כאמור, רץ במסוף. כ-כזה, הוא מכיל מספר גדול של פקודות, בחלקן תשתמשו באופן יום-יומי, בחלקן לעיתים נדירות.
אם רמת ההיכרות הנוכחית שלכם עם הכלי מבוססת על המדריך הזה, יש 4 פקודות ששווה שתכירו:
composer install
מתקינה את תלויות הפרוייקט לפי הקובץ composer.lock
או composer.json
, אם הראשון לא קיים מבצעת את הפקודה update
composer update
מתקינה את תלויות הפרוייקט לפי הקובץ composer.json
וכותבת קובץ composer.lock
חדש
composer require vendor/package:version
מוסיפה לקובץ composer.json
את החבילה שצוינה ומריצה את הפקודה composer install/update
composer remove vendor/package
מוחקת מקובץ composer.json את החבילה שצוינה ומריצה את הפקודה composer update
תנו לעצמכם טפיחה על השכם: התמדתם והגעתם לסוף המאמר – ריספקט.
אני מקווה שהצלחתי ללמד אתכם את המהות של Composer ואיך להשתמש בו.
אבל אל תיכנסו לאופוריה! עוד יש לנו על מה לעבור ואני מבטיח שאני ארשום מאמר המשך עם נושאים מתקדמים יותר כמו התקנת חבילות גלובלית, טעינה אוטומטית, כתיבת חבילות ועוד.
עד לפעם הבאה
הפוסט המדריך השלם ל – Composer הופיע ראשון בMasterScripter