تعداد بازدید: 3027

Composer (قسمت اول)

composer یک ابزار رابط خط فرمان (command line interface) برای مدیریت و نصب پروژه های PHP می باشد. بوسیله آن می توان روی پروژه خود پکیج هایی (پروژه ها یا کتابخانه ها) را نصب کنید یا بالعکس پروژه خود را قابل نصب بر روی پروژه های دیگر کنید.

مواردی که در این درسنامه بررسی می گردد :

  • Composer Dependency Manager
  • Package Properties
  • Package links
  • Autoload mapping

Composer Dependency Manager

این ابزار را باید روی سیستم عامل خود نصب و پیکره بندی کنید و پروژه ها را با استفاده از آن بسازید و پکیج هایی را نیز به پروژه خود اضافه کنید و در نهایت پروژه ها را به همراه کتابخانه ها به هر جا منتقل کنید.

پروژه یا کتابخانه یا پکیج دارای یک عملکرد رفتاری می باشند. شما نرم افزار در حال توسعه خود را یک پروژه می نامید. اگر آن را به packagist منتقل کنید می توان به آن یک کتابخانه یا پروژه قابل نصب برای دیگران کنید حال پیش نیاز هایی دیگر از سایر کتابخانه ها (dependency manager ) نیز داشته باشد.

ساختار کلی یک پروژه PHP ساخته شده مبتنی بر Composer :

  • composer.json : تنظیمات اصلی پکیج یا پروژه که شامل اطلاعات کلی پروژه (properties) و کتابخانه های نصب شده روی پکیج می باشد.
  • composer.lock : این فایل نمایش دهنده وضعیت جاری پروژه می باشد. شامل ورژن پکیج های نصب شده روی پروژه و … .
  • vendor : فروشنده های پکیج. هر پکیج در packagist یک فروشنده دارد که وقتی آن را در کامپیوتر خود می سازد از روی نام کاربر سیستم عامل ساخته می شود. در این دایرکتوری لیست پکیج ها می باشد و همچنین فایل autoload و composer .

Package Properties

اطلاعاتی در رابطه با پکیج یا پروژه می باشد که در فایل composer.json موجود می باشد. این اطلاعات شاخصه پکیج شما در مکان های مختلف می باشد.

به طور مثال زمانی که خط فرمان پکیج ها را لیست میگیریم و یا در packagist زمانی که پروژه را قرار می دهید این اطلاعات از composer.json خوانده می شود و نمایش داده می شود.

برخی از شاخصه های پکیج (Package Properties) که در فایل composer.json موجود می باشد :

name : نام پکیج یا پروژه که به صورت ترکیبی از نام vendor و نام پروژه می باشد. به طور مثال tymon/jwt-auth که tymon نام vendor و jwt-auth نام پکیج می باشد. یا symfony/console که symfony نام vendor می باشد و console پکیج می باشد.

description : توضیحات پروژه یا پکیج یا کتابخانه.

version : ورژن پکیج که از فرمت X.Y.Z یا vX.Y.Z پیروی می کنند. به طور مثال 1.0.2 یا v2.0.4 .

type : این نوع پروژه را مشخص می کند و بر اساس همین نوع منطق نصب پکیج متقاوت خواهد بود. پروژه می تواند از نوع کتابخانه (library) , پروژه (project) باشد و همچنین خودتان هم می توانید نوع جدیدی ایجاد کرده و منطق نصب لازم را برای آن تعیین کنید به طور مثال پلاگین وردپرس (wordpress-plugin) , یا ماژولی برای سیستم هایی نظیر symfony (symfony-bundle) باشد.

مثلا laravel یک project است و illuminate/database یک Library می باشد. زمانی که در packagist در حال جستجو هستید در سمت راست یک لیست از package type ها جهت فیلتر وجود دارد.

نکته : برای نصب project باید از دستور create-project استفاده کنید و برای نصب Library باید از دستور require استفاده کنید.

keyword : آرایه ای از کلمات کلیدی مرتبط با پروژه .

authors : نویسنده های پکیج که هر کدام به شکل یک شئ با خصوصیاتی نظیر homepage , name , email , role می باشند.

نکته : هر یک از این شاخصه ها می تواند اجباری یا اختیاری یا به صورت ساختمان داده های رشته ای یا آرایه ای یا شئ باشند.

به دوحالت می توانید این اطلاعات را پر کنید . یا اینکه فایل composer.json را دستی بسازید و فرمان composer install را وارد کنید یا با دستور composer init یک installation wizard را بالا بیاورید و یک به یک این مقادیر را وارد کنید.

Package links

پکیج هایی که روی پروژه نصب می کنید به صورت یک شئ از مقدار نام و ورژن نصب می شود "josh/faker": "1.0.0". برای نصب پکیج نیز از همین ترکیب استفاده می کنیم.

روش اول ) در فایل composer.json ترکیب را وارد می کنیم و دستور composer install رو وارد می کنیم.

"require": {
   "josh/faker": "1.0.0"
}

برای تغییر ورژن نیز می توان فایل composer.json را تغییر داد و فرمان composer update را وارد کنید.

روش دوم ) با استفاده از فرمان composer require پکیج را نصب کنید.

composer require "josh/faker 1.0.0"

در فرمان بالا پکیج josh/faker ورژن 1.0.0 را نصب کردیم. برای استفاده از پکیج های نصب شده باید ابتدا فایل autoload.php را فراخوانی کنیم (این فایل در دایرکتوری vendor می باشد) و namespace ماژول های مورد نیاز را use کنیم. برای ادامه کار می توانید به مستندات پکیج مراجعه کنید.

با استفاده فرمان composer remove josh/faker می توان پکیج josh/faker را حذف کنیم . همچنین برای بروزرسانی فایل autoload.php می توانید فرمان composer dump-autoload را وارد کنید.

اگر بخواهید یک پروژه را به صورت کامل کپی بگیرید و به عنوان یک پروژه جدید برای خود نصب کنید باید دستور زیر را اجرا کنید :

composer create-project PACKAGENAME

ممکن است شما یک پروژه داشته باشید و یک پرژه (مثلا faker) را روی آن نصب کنید و یا یک پروژه را به صورت کامل بهمراه comopser properties به عنوان پروژه خود نصب کنید. به طور مثال فرض کنید که پروژه josh/faker را به دو صورت create-project و install نصب می کنیم.

روش اول ) دستور زیر را برای ساخت پروژه جدید از روی josh/faker اجرا می کنیم و ساختار فایل آن را مشاهده می کنیم.

composer create-project --prefer-dist josh/faker persianFaker

یک دایرکتوری با نام persianFaker ساخته شده و پروژه josh/faker در آن قرار می گیرد. (بهمراه تنظیمات composer.json پروژه faker)

این دستور یک دایرکتوری با نام persianFaker می سازد و faker را به همراه تمامی فایل ها و dependency های آن برای شما نصب می کند.

روش دوم ) ابتدا یک پروژه با استفاده از composer init می سازیم و بعد دستور زیر را می زنیم تا کتابخانه josh/faker روی آن نصب گردد.

composer require josh/faker

ساختار فایل ها در این روش به شکل زیر می باشد:

init/
    vendor/
        composer
        josh/
composer.json
composer.lock

تنظیمات composer.json در این روش برابر با مقادیریست که در زمان init ساختیم.

نکته : در ساخت پروژه ما اپشن های prefer-dist و prefer-source را داریم :

  • prefer-dist : این روش نصب بدون VSC یا همان none version control می باشد.
  • prefer-source : نصب پروژه به همراه VSC یا version control می باشد. در انتهای این روش مجددا از شما می پرسد که فایل گیت را پاک کند یا خیر.

Autoload mapping

با استفاده از composer می توانیم تمامی فایل های پروژه خود را با استفاده از فایل autoload.php فراخوانی کنیم. برای این کار از autoload در فایل composer.json استفاده می کنیم. برای این کار به سه کلید psr-4 , classmap , files نیاز داریم :

  • psr-4 : یک convention می باشد برای نحوه نامگذاری namespace ها در پروژه. به طوری که با توجه به ساختار پوشه بندی ها namespace ها را انتخاب می کنیم. مثلا کلاس Cat واقع در مسیر animals/demonstic/Cat.php باید namespace برابر با Animals\Demonstic بگیرد و همچنین نام کلاس شما باید هم نام با نام فایلی که در آن وجود دارد باشد. این مقدار به صورت شئ مقدار دهی می شود.
  • classmap : آرایه ای از آدرس فایل ریشه کلاس ها را به آن می دهیم و تمامی کلاس های موجود در آن دایرکتوری را فراخوانی می کند.
  • files : آرایه ای از فایل های مورد نیاز برای فراخوانی را به آن می دهیم.

به طور مثال فرض کنید یک پروژه داریم ساختار فایل های زیر را دارد :

animals/
    demonstics/
        Cow.php
        Hen.php
        Lamb.php
    Wilds/
        Tiger.php
        Lion.php
        Elephent.php
staff/
    Manager.php
    Zookeeper.php
    Vet.php
vendor/
composer.json
functions.php
index.php

در ساختار دایرکتوری بالا ما autoload رو به شکل زیر می سازیم :

"autoload": {
    "psr-4": {
        "Animals\\":"animals/"
    },
    "classmap": [
        "staff"
    ],
    "files": [
        "functions.php"
    ]
}

برای فراخوانی کلاس های animals از psr-4 استفاده کرده ایم و برای فراخوانی کلاس های staff از classmap و برای فراخوانی functions.php از files استفاده کرده ایم.

دقت داشته باشید باید دایرکتوری animals با توجه به convention psr-4 namespace گذاری شده باشد. در پایان از این کلاس ها در فایل index.php استفاده می کنیم :

<?php
require __DIR__ . '/vendor/autoload.php';
/**
 * using psr-4 convention
 */
use Animals\Domestics\Lamb;
$lamb = new Lamb;
$lamb->intro();
echo '<br>';
/**
 * using classmap
 */
$zookeeper = new ZooKeeper;
$zookeeper->intro();
echo '<br>';
/**
 * using files
 */
open();

نکته : شما همان طور که autoload دارید autoload-dev هم می توانید داشته باشید که در زمان نصب (require) برای کاربر این فایل ها include نمی شوند.بوتسترپ فایل های require-dev نیز همان vendor/autoload.php می باشد. همچنین اگر --no-dev را همراه با دستور composer dump-autoload بزنید تنها فایل های require برای شما autoload می شوند.

نتیجه گیری

برای نصب یک کتابخانه می توان یک پروژه را به صورت خام init کرد و dependency های آن را چه برای require , require-dev تعیین کرد و فایل composer.json آن را تغییر داد و بعد composer install را اجرا کرد و یا اینکه برای نصب کتابخانه در پروژه موجود از فرمان composer require استفاده کرد .

اگر پروژه را به صورت کامل به همراه تنظیمات composer آن می خواهید از فرمان composer create-project استفاده می کنید(مثلا برای ساخت وب سایت با لاراول) در این صورت composer.json پکیج که نصب کرده اید شناسنامه پروژه جاری شما خواهد بود و تمامی require و require-dev ها در آن نصب می گردد.

پکیج تا زمانی که روی سیستم شما در حال توسعه است در development mode می باشد . زمانی که به عنوان یک پکیج روی یک پروژه نصب گردد composer از روی فایل تنظیمات (composer.json) فایل های autoload و require را می خواند و به autoload اصلی پروژه اضافه می کنید. به همین دلیل vendor , composer.lock در .gitignore قرار گرفته اند. یعنی شناسنامه پکیج شما همان composer.json می باشد و در زمان نصب دیگر نیازی به دایرکتوری vendor و autoload آن نمی باشد.در نتیجه پکیج هایی که برای محیط development هست را در require-dev نصب کنید.

مطالب مشابه

ساخت REST API با PHP

API (Application Program Interface) یعنی یک واسط برای استفاده از امکانات نرم افزار. واسط های گرافیکی نرم افزار رو هم می...

FileSystem در PHP

رفتار تابعی در مقابله با فایل ها و دایرکتوری ها دقیقا مثل رفتار نرم افزار های FileManager ها در سیستم عامل هاست. Action...

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

2 دیدگاه برای Composer (قسمت اول)

  1. با سلام
    ببخشید بنده کامپوزر را در وردپرس نصب کرده ام و اتولود کردن کلاس ها رو با کامپوزر هندل کرده ام.
    ولی ارور میده هنگامی که از autoload composer استفاده میکنم و اسم و مسیر دقیق کلاس رو هم کیگیره و اینکلود میکنه ولی وردپرس این ارور رو میده:
    Warning: call_user_func_array() expects parameter 1 to be a valid callback, class ‘initialiser’ not found in C:\xampp\htdocs\wordpress-specialist\j5-wordpress-theme\wp-includes\class-wp-hook.php on line 286
    و هنگامی هم که با تابع spl_autoload_register پی اچ پی خودم اتولود مینویسم کار میکند در وردپرس ولی مشکل آن این است که هنگام فراخوانی یک کلاس در پلاگین ها این تابع نام کلاس را میگیرد و به مسیر قالب ارجاع میده. چطوری باید به spl_autoload_register بگویم فقط کلاس های قالب رو هندل کن و کاری به توابع و کلاس های افزونه ها نداشته باش؟
    ممنون میشم راهنمایی بفرمایید که چگونه در وردپرس با کامپوز اتولو بنویسم و این اتولود فقط مخصوص قالب باشد و کاری به کلاس های افزونه ها نداشته باشد.

    • با سلام و احترام
      دوست عزیز اشتباه شما ممکنه یکی از این دلایل باشه :

      • اگر از namespace استفاده کرده باشی توی الگوریتم اوتولود در مکان فراخوانی use نشده باشه.
      • آیا هوک رو به درستی استفاده کردی ؟ نحوه قلاب کردن متد های یک کلاس به یک هوک رو در مستندات وردپرس جستجو کن.

      در پایان چرا میخوای توی تم وردپرس از کامپوزر استفاده کنی ؟ نحوه autoload شدن قالب های وردپرس بر عهده هسته است و در تم شما باید تا حدودی قسمت view وب سایت رو تکمیل کنی و این که یک autoload جدید با کامپوزر بسازی برای فایل های خودت کار اشتباهیه.
      توی موارد خاص در پلاگین ها میشه از کامپوزر استفاده کرد. کما این که اونجا هم گاها ترتیب ساخت اشیاء ممکنه دردسر ساز باشه و یک autoload دستی خیلی بهتر میتونه کمکت کنه. معمولا اگر نیاز به نصب یک کتابخانه پیش اومد از کامپوزر در پلاگین ها استفاده کن. ضمن این که به این نکته توجه داشته باش که امکانات بدنه وردپرس نباید وابسته به تم باشه و باید در پلاگین پیاده سازی بشه.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *