آموزش استفاده از Composer در PHP

چرخ را دوباره اختراع نکنید! همه ما توسعه دهنده های نرم افزار در پروژه هایی که توسعه می‌دهیم به ابزاری نیاز داریم که توسط دیگر توسعه دهنده ها از پیش ساخته و منتشر شده. ما می‌توانیم به جای بازطراحی آنها فقط تصمیم بگیریم که از آنها استفاده کنیم! اما استفاده از این ابزار ها یا به اصطلاح پکیج ها خودش به پیچیدگی هایی ختم می‌شود که مجبور می‌شویم به دنبال راهکار هایی برای آن بگردیم که البته راه حل مناسب استفاده از یک ابزار مدیریت وابستگی است و در این باره نیز باید گفت چرخ را دوباره اختراع نکنید!Composer the PHP Depebdency Managerمدیریت وابستگیهمانطور که پیشتر اشاره کردیم وقتی برای توسعه یک پروژه از پکیج های آماده که توسط دیگران ساخته شده استفاده می کنیم پیچیدگی هایی پیش می آید که نیازمند مدیریت هستند. در ادامه دو مورد از این پیچیدگی ها را بررسی می کنیم.بروزرسانی وابستگی هاپکیج ها همانند نرم افزار ها در طول زمان توسعه داده می‌شوند و یا باگ های موجود در آنها رفع می شود و نسخه های جدیدی از آنها منتشر می‌شود. به عنوان مصرف کننده باید آنها را به روز نگه داشته تا کیفیت و امنیت محصول خود را تضمین کنیم. علاوه بر به بروزرسانی مداوم پکیج های مورد استفاده باید به هنگام بروزرسانی به نسخه جدید سازگاری نسخه جدید با پروژه خود را بررسی کنیم تا مبادا پروژه دچار مشکل شود.وابستگی های تو در توپکیج های مورد نیاز پروژه (وابستگی های سطح اول) برای ارائه کاربرد مورد نظر ممکن است از پکیج های دیگر استفاده کنند و خود وابستگی هایی که آنرا وابستگی های سطح دوم می‌نامیم داشته باشند. این داستان ممکن است ادامه دار باشد و حتی وابستگی های سطح سوم، چهارم و … هم به وجود بیایند. برای مدیریت این مسئله دو راهکار را می‌توان در نظر گرفت: ۱) برای هر پکیج وابستگی های آن را در دایرکتوری همان پکیج قرار بدهیم و سلسله مراتبی از وابستگی ها به وجود بیاوریم. ۲) همه پکیج ها از همه سطوح وابستگی را بدون اینکه تفاوتی برای سطح آنها قائل شویم را در کنار هم قرار دهیم.در راهکار اول مدیریت بسیار ساده تر می‌باشد اما با توجه به اینکه در واقعیت بسیاری از وابستگی ها مشترک هستند حجم بسیار زیادی از پکیج تکراری خواهیم داشت و عملا این راهکار ناکارآمد است.در راهکار دوم که معمولا راهکار برگزیده ابزار های مدیریت وابستگی می‌باشد، همه وابستگی ها از سطوح مختلف در کنار هم نگهداری می‌شوند تا از دانلود مجدد و نگهداری آنها در مکان های مختلف جلوگیری شود. در این راهکار باید نسخه پکیج مورد نظر را با دقت انتخاب کنیم که سازگار با تمام پکیج های دیگر و پروژه اصلی باشد.ابزار مدیریت وابستگیبا توجه توضیحاتی که شرح دادیم لزوم وجود یک ابزار نیرومند برای مدیریت وابستگی ها در پروژه های نرم افزاری کاملا احساس می‌شود. مهمترین وظیفه این ابزار دانلود نسخه مناسب از پکیج های مورد نیاز از مخزن های تعریف شده و قرار دادن آنها در اختیار توسعه دهنده و پروژه است.برای زبان های برنامه نویسی مختلف ابزار های مختلفی طراحی شده است؛ برای مثال Maven و Gradle برای جاوا، pip برای پایتون، SBT برای اسکالا و Dep برای Go را می توان نام برد. برای زبان برنامه نویسی PHP در گذشته از ابزار Pear استفاده می‌شد اما سال ‌هاست که Composer نه به عنوان ابزار رسمی اما به عنوان محبوب ترین ابزار مدیریت وابستگی در پروژه های PHP استفاده می‌شود.قرارداد نامگذاری نسخه هایکی از مباحث مهمی که باید در استفاده و توسعه وابستگی ها به آن توجه کنیم قرارداد نامگذاری نسخه ها است. قرارداد های مختلفی در این زمینه وجود دارد. محبوب ترین این قرارداد ها که توسط سایت semver.org تعریف شده به این صورت است:MAJOR.MINOR.PATCHدر این قرارداد نامگذاری، نسخه پکیج (یا نرم افزار) از سه بخش تشکیل می‌شود که ادامه هر کدام را توضیح می‌دهیم.بخش MAJOR در نسخه هابخش اول در نام نسخه Major نام دارد که بخش اصلی نسخه پکیج به حساب می آید و تغییر آن به معنی وجود تغییرات بنیادی یا مهم در نسخه جدید پکیج است و لزوما با نسخه قبلی سازگار نمی‌باشد. در صورتی که ما توسعه دهنده پکیج هستیم و در نسخه جدید تغییراتی در رابط کاربری (API) پکیج ایجاد کرده‌ایم که کاربران نسخه قبلی بدون تغییر نمی‌توانند از این نسخه استفاده کنند، ما این بخش از نسخه را یک واحد افزایش می دهیم. برای مثال اگر نسخه قبلی پکیج ما 2.6.1 بوده نسخه جدید را باید 3.0.0 نامگذاری کنیم. در صورتی که ما کاربر یک پکیج هستیم باید به هنگام بروزرسانی پکیج توجه کنیم که با بروزرسانی به نسخه با Major بالاتر، ممکن است به تغییراتی در پروژه برای سازگاری با نسخه جدید نیازمند باشیم.بخش MINOR در نسخهبخش دوم در نام نسخه Minor نام دارد که بخش فرعی پکیج به حساب می‌آید و تغییر آن به معنی معرفی شدن فیچر (قابلیت) جدید یا بهبود قابل توجه با حفظ سازگاری با نسخه قبلی است. برای مثال اگر نسخه پکیج 2.6.1 است، چنین تغییری می‌تواند به نسخه 2.7.0 منجر شود. با توجه توضیحات ذکر شده می توان با خاطری نسبتا آسوده پکیج ها را به نسخه با Minor بالاتر بروزرسانی کنیم.بخش PATCH در نسخهبخش سوم نام نسخه Patch نام دارد که تغییر آن معمولا بخاطر تغییرات کوچک (برای مثال رفع باگ) است و معمولا هیچ قابلیت جدیدی برای معرفی وجود ندارد. Patch های جدید با نسخه قبلی باید کاملا سازگار باشند.ابزار Composerهمانطور که اشاره کردیم Composer محبوب ترین ابزار مدیریت وابستگی برای پروژه های مبتنی بر زبان برنامه نویسی PHP می‌باشد که فریم ورک های معروف PHP از جمله Laravel و Symfony از این ابزار استفاده می‌کنند. این ابزار امکانات بسیاری را در اختیار توسعه دهنده ها قرار می‌دهد و ما سعی کردیم در این مقاله تعدادی از آنها را معرفی کنیم.کمپوزر بطور پیشفرض از مخزن packagist.org برای دانلود پکیج ها استفاده می‌کند. در سایت مربوط به این مخزن می‌توانید پکیج های قابل استفاده را مشاهده کنید.نصب Composerکومپوزر را می توانید از سایت getcomposer.org دانلود و نصب کنید. در ادامه روش نصب این ابزار را در سیستم عامل های مک، ویندوز و توزیع های لینوکس را توضیح می‌دهیم.در سیستم عامل Mac OS می‌توانید از ابزار Homebrew استفاده کنید و با اجرای فرمان زیر در ترمینال Composer را نصب کنید.brew install composerدر سیستم عامل ویندوز می‌توانید فایل نصب را از سایت getcomposer.org دانلود و اجرا کنید. پس از نصب آن باید مسیر (آدرس فولدر) فایل اجرایی Composer را به Path های سیستم اضافه کنید.در توزیع های لینوکس با اجرای دستورات زیر می‌توایند Composer را نصب کنید.curl -sS https://getcomposer.org/installer -o composer-setup.php sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composerپس از نصب Composer می توانید صحت نصب را با اجرای دستور زیر در خط فرمان (ترمینال) بررسی کنید.composer --versionنصب وابستگی های پروژهدر صورتی که در پروژه خود به یک پکیج نیاز دارید ابتدا باید آنرا در مخزن packagist.org پیدا کنید. در صفحه مربوط به پکیج در سایت Packagist می توانید روند افزودن آن به پروژه مشاهده کنید. برای مثال برای افزودن پکیج miladrahimi/phprouter به پروژه می‌توانید دستور زیر را در دایرکتوری پروژه اجرا کنید.composer require miladrahimi/phprouterبا افزودن اولین وابستگی به پروژه، Composer دو فایل composer.lock و composer.json و همچنین دایرکتوری vendor را به پروژه شما اضافه می‌کند و در صورت وجود این فایل ها و دایرکتوری، آنها را بروزرسانی می‌کند.برای افزوده شدن وابستگی به پروژه، Composer آنرا از مخزن packagist.org دانلود کرده و در دایرکتوری vendor قرار می‌دهد. در ادامه وابستگی مورد نظر را به بخش require در فایل composer.json اضافه می‌کند و نهایتا composer.lock را هم مطابق با composer.json و نسخه دقیق نصب شده بروزرسانی می‌کند.در صورتی که پکیج مورد نظر تنها در روند توسعه پروژه کاربرد دارد و در سرور اصلی نیازی به نصب آن نیست، می‌توانید با دستوری مشابه دستور زیر آنرا به پروژه اضافه کنید.composer require phpunit/phpunit --devدستور بالا پکیج phpunit/phpunit را به بخش require-dev در composer.json اضافه خواهد کرد.چنانچه نسخه خاصی از پکیج مد نظرتان هست می‌توانید همانند دستور زیر آنرا به پروژه به اضافه کنید:composer require miladrahimi/phprouter:&quot5.0&quotبا اجرای دستور بالا نسخه 5.0 از پکیج مورد نظر نصب می‌شود. از آنجایی که نسخه ذکر شده فاقد بخش Patch می‌باشد، کمپورز آخرین Patch (برای مثال 5.0.2) نصب می‌کند.به مثال دیگری که در ادامه آورده ایم هم توجه کنید.composer require miladrahimi/phprouter:&quot5.*&quotبا اجرای این دستور نسخه *.5 از پکیج نصب خواهد شد. Composer جدیدترین نسخه از پکیج که بخش Major آن 5 می‌باشد (برای مثال نسخه 5.1.0) را نصب خواهد کرد.برای مشاهده دیگر فرمت های نوشتن نسخه که توسط Composer معرفی شده است می تواند به مقاله رسمی سایت Composer با نام Versions and constraints مراجعه کنید.فایل composer.jsonفایل composer.json پس از اجرای دستور init یا افزودن اولین وابستگی به پروژه در دایرکتوری پروژه ایجاد می‌شود. این فایل را که می‌توان به طور دستی و با یک Text Editor هم ساخت، شامل لیست وابستگی ها (پکیج ها مورد نیاز پروژه)، مخزن ها، Auto-loader ها و همه اطلاعاتی است که Composer از پروژه شما نیاز دارد که بداند.در این فایل نسخه پکیج ها را می توان بصورت انعطاف پذیر همانند *.v3 یا *.v3.6 نوشت تا بروزرسانی پکیج ها و همچنین جلوگیری از نصب نسخه غیر قابل سازگار ممکن باشد.فایل composer.lockفایل composer.lock که در کنار فایل composer.json قرار می‌گیرد شامل اطلاعات دقیق از آخرین نصب یا بروزرسانی وابستگی ها می باشد. این فایل به هنگام اجرای دستور install مورد استفاده قرار می‌گیرد تا از نصب ناخواسته نسخه های جدید در محیط های حساس جلوگیری شود. پیشنهاد می شود این فایل به همراه پروژه به سرور منتقل شود تا با نصب وابستگی ها در سرور مطمئن باشیم همان نسخه استفاده شده در محیط تست (یا توسعه) بر روی سرور نصب می‌شود.دایرکتوری vendorاین دایرکتوری حاوی تمام پکیج های دانلود شده توسط Composer می‌ باشد که مورد نیاز پروژه است. علاوه بر پکیج های نصب شده، اطلاعات مربوط به نحوه بارگذاری آنها و همچنین فایل autoload.php در این دایرکتوری نگهداری می شود.با توجه به اینکه با استفاده از اطلاعات موجود در فایل های composer.json و composer.lock و نرم افزار Composer هر زمان و هر کجا می توان مجددا تمام پکیج های مورد نیاز پروژه را نصب کرد به هنگام به اشتراک گذاری، آپلود به سرور یا مخزن Git و Deploy این دایرکتوری را می‌توان git ignore کرد.بارگذاری خودکار (Autoload) پکیج هاهمانطور که قبلا گفتیم Composer پکیج های مورد نیاز پروژه را پس از دانلود در دایرکتوری vendor قرار می‌دهد. Composer همچنین فایلی به نام autoload.php در این دایرکتوری ایجاد می‌کند. این فایل حاوی Auto-loader برای تمام پکیج های نصب شده توسط Composer است و با require کردن آن در پروژه می‌توان از پکیج های نصب شده استفاده کرد. مثال زیر نحوه استفاده از پکیج miladrahimi/phprouter را نشان می‌دهد:<?php require &quotvendor/autoload.php&quot use MiladRahimi\PhpRouter\Router; $router = Router::create(); $router->get('/', function () { return 'Hello World!'; }); $router->dispatch();بروزرسانی وابستگی هاپس از نصب وابستگی ها ممکن است نیاز باشد که آنها را بروزرسانی کنیم. در این صورت می‌توانید از دستوری مشابه دستور زیر استفاده کنید.composer update miladrahimi/phprouterپس از اجرای دستور بالا جدیدترین نسخه سازگار (مطابق با composer.json) از پکیج مورد نظر توسط Composer دانلود و جایگزین نسخه قبلی آن در دایرکتوری vendor می‌شود. همچنین فایل composer.lock هم بروزرسانی می شود اما هیچ تغییر در فایل composer.json نخواهیم داشت.در صورتی که می‌خواهید همه وابستگی ها را بروزرسانی کنید می‌توانید از دستور زیر استفاده کنید.composer updateاین دستور تمام وابستگی ها، دایرکتوری vendor و فایل composer.lock را بروزرسانی می‌کند. این دستور را با دستور زیر که خود نرم افزار Composer را بروزرسانی می‌کند اشتباه نگیرید.composer self-updateنصب وابستگی ها در سرورهمانطور که قبلا توضیح دادیم بهتر است دایرکتوری vendor را به هنگام آپلود پروژه در سرور یا در مخزن هایی مانند گیتهاب ignore کرد. همچنین در صورتی که بطور کلاسیک برای Deploy پروژه روی سرور آنرا آپلود می کنید. در این صورت به هنگام دریافت پروژه، دایرکتوری vendor را نداریم اما می‌توان با دستور زیر مجددا وابستگی ها را نصب کنیم.composer installدستور بالا در صورتی که فایل composer.lock وجود داشته باشد، پکیج ها را مطابق با نسخه دقیق ثبت شده در آن نصب می‌کند و در غیر این صورت با استفاده از اطلاعات موجود در فایل composer.json آخرین نسخه سازگار با پروژه را نصب خواهد کرد.در محیط هایی همانند سرور اصلی با استفاده از پارامتر no-dev-- می‌توانید از نصب پکیج های مورد نیاز محیط های تستی جلو گیری کنید.composer install --no-devتعریف autoload پروژه یکی از قابلیت های مفیدی که Composer ارائه می دهد، امکان تعریف autoload برای پروژه است. در بخش های قبل متوجه شدیم که برای بارگذاری پکیج های دانلود شده توسط Composer باید فایل vendor/autoload.php در پروژه خود require کنید. از طرفی پروژه شما هم به یک Auto-loader برای بارگذاری کلاس های پروژه نیاز دارد. با قابلیت مورد نظر نیاز نیست که شما به طور جداگانه یک Auto-loader طراحی کنید، تنها کافیست تا اطلاعات بارگذاری پروژه را به composer.json اضافه کنید تا همان autoload موجود در دایرکتوری vendor کلاس های پروژه شما را هم بارگذاری کند.&quotautoload&quot: { &quotpsr-4&quot: {&quotApp\\&quot: &quotapp/&quot} }با افزودن بخش بالا به فایل composer.json، کمپوزر مطابق با استاندارد PSR-4 کلاس هایی که namespace آنها با عبارت App شروع می‌شود را از دایرکتوری app درون دایرکتوری پروژه بارگذاری میکند. برای مثال:App\Models\User => ./app/Models/User.php App\Controllers\Admin\UsersController => ./app/Controllers/Admin/UsersController.phpمخزن هاسرور Packagist مخزن رسمی و عمومی Composer است و Composer برای نصب پکیج ها به این مخزن رجوع می کند. با وجود مخزن Packagist برای پکیج های خصوصی و یا پکیج هایی که در این مخزن رجیستر نشده‌اند ما به مخزن های ثانویه نیازمندیم که خوشبختانه Composer به راحتی به ما اجازه می‌دهد تا این مخزن ها را برای پروژه تعریف کنیم.در صورتی که مخزن مورد یک مخزن خصوصی در یک سرور Git همانند GitHub یا GitLab است، می‌توانید با آنرا همانند کد زیر به فایل composer.json اضافه کنید.&quotrepositories&quot: [ { &quottype&quot: &quotgit&quot, &quoturl&quot: &quothttps://github.com/private-company/foo&quot } ], &quotrequire&quot: { &quotprivate-company/foo&quot: &quot1.*&quot }در صورتی که پکیج مورد نظر شما فقط در قالب تعدادی فایل در کامپیوتر دسترس است می‌توانید به شکل زیر آنرا در composer.json اضافه کنید.&quotrepositories&quot: [ { &quottype&quot: &quotpath&quot, &quoturl&quot: &quot../../packages/my-package&quot } ], &quotrequire&quot: { &quotmy/package&quot: &quot*&quot }برای اطلاعات بیشتر در زمینه مخزن ها می توانید بخش Repositories از مستندات رسمی Composer را مطالعه کنید.گفتار پایانیدر این مقاله با مفاهیم مقدماتی از Composer آشنا شدید اما برای مطالعه بیشتر و آشنایی بیشتر با قابلیت های این ابزار مفید می توانید به مستندات رسمی مراجعه کنید.