Composer е най-страхотният инструмент за всеки PHP разработчик, който направи управлението на зависимости за всякакви пакети на приложения безпроблемно.

В следващите раздели няма да говоря за основната функция на композитора - която е управлението на зависимости - и ще се съсредоточа върху това как приложенията управляват зареждането на голям брой пакети от композитор.

  1. Какво е автоматично зареждане.
  2. Нека създадем нашия автоматичен зареждащ механизъм.
  3. Как Composer прави автоматично зареждане.
  4. Classmap срещу PSR-0 срещу PSR-4.
  5. Заключение.
  6. Препратки.

1. Какво е автоматично зареждане

Едно от най-големите неприятности е да напишете дълъг списък с необходими включвания в началото на всеки скрипт.

Проблем: Да предположим, че разработвате приложение и имате дълъг списък от библиотеки, които трябва да бъдат заредени.

Решение: Заредете всички класове в началото на вашия скрипт и ще можете да използвате всеки един от тези класове навсякъде в приложението си.

По-добро решение: Всеки път, когато използвам клас, отивам и го зареждам, така че приложението ми не трябва да зарежда всички класове при всяка заявка, това се нарича „Автоматично зареждане”. Но как да постигнем това?… нека разберем:

2. Нека създадем нашия Autoloader

Най-простото решение включва всички файлове:

<?php
// Classes/A.php
class A {}
<?php
// Classes/B.php
class B {}
<?php
// index.php
include_once 'Classes/A.php';
include_once 'Classes/B.php';
// load A class
$a = new A();
// check the list of all loaded files
var_dump(get_included_files());

Скриптът index.php ще изведе:

array(3) {
  [0]=> string(20) "/path/to/root/index.php"
  [1]=> string(24) "/path/to/root/Classes/A.php"
  [2]=> string(24) "/path/to/root/Classes/B.php"
}

Което означава, че сме заредили всички файлове независимо дали сме използвали клас B или не, и докато вашият проект става все по-голям и по-голям, този начин няма да работи.

Ето го и автоматичното зареждане за решаване на проблема:

<?php
// index.php
// my custom autoloader
function my_autoloader($class) {
  include 'Classes/' . $class . '.php';
}

// register the autoloader
spl_autoload_register('my_autoloader');

// load A class
$a = new A();

// check the list of all loaded files
var_dump(get_included_files());

Вие пишете начина, по който правите „съпоставяне“ между името на класа и неговия файлов път във функцията my_autoloader() и го регистрирате във вашия скрипт, така че да кажете на скрипта си, че всеки път, когато създавате клас, просто отидете и потърсете чрез тази функция и го заредете. Сега проверете броя на файловете, заредени във вашия скрипт:

array(2) {
  [0]=> string(50) "/path/to/demos/autoload-2/index.php"
  [1]=> string(54) "/path/to/demos/autoload-2/Classes/A.php"
}

Сега вашият скрипт зарежда файловете, които са му необходими.

PHP ви казва „Ще ви дам шанса да отидете и да заредите класа си, дори ако не сте го заредили преди оператора си $a = new A(); след това, ще хвърля грешка, ако не работи“.

Предходният пример работи добре, но трябва да имате предвид следното:

  1. Името на файла трябва да има същото име на клас.
  2. Всеки отделен файл трябва да има само един клас.
  3. Чувствителност в имената на класовете и имената на файловете.

Можете да се справите с всички тези ситуации със собствена реализация и всяко приложение може да направи свое собствено картографиране въз основа на своята файлова структура, но за да използвате този автозареждащ механизъм, трябва да следвате предходните съображения.

Composer измисля начин, който отговаря на повечето структури (или можете да кажете, че принуждава приложенията да избират между), нека се заровим малко по-дълбоко в него.

3. Как Composer прави автоматично зареждане

Заедно с вашия скрипт index.php добавете вашия composer.json:

{
  "autoload": {
    "classmap": [
      "Classes/"
    ]
  }
}

И актуализирайте вашия файл index.php до:

require __DIR__ . '/vendor/autoload.php';

$a = new A();

Използвайки classmap, ние казваме на композитора, че това е начинът да се направи картографиране и това е много основен начин за картографиране на пространства от имена към пътища и ако искате повече подробности, просто маркирайте vendor/composer/autoload_classmap.php, след като изпълните composer install:

return array(
  'A' => $baseDir . '/Classes/A.php',
  'B' => $baseDir . '/Classes/B.php',
);

И всеки път, когато създавате клас A, той зарежда файла $baseDir . '/Classes/A.php'.

Потокът е лесен за разбиране. Винаги започва от следния ред във вашия преден контролер:

require __DIR__.'/../vendor/autoload.php';

И ще разберете, че ComposerAutoloaderInitXXXX:getLoader() има цялата логика, която добавя различни съпоставяния и в края на това регистрира автоматичното зареждане:

// \Composer\ComposerAutoloaderInitXXXX:getLoader()
public static function getLoader() {
  ...
  $loader->register(true); // \Composer\ClassLoader::register()
  return $loader;
}

И ето къде регистрираме нашия автозареждащ механизъм:

// \Composer\ClassLoader::register()
public function register($prepend = false) {
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}

И всеки път, когато създадем клас, той отива до ClassLoader::loadClass(), за да намери съответния файл и да го зареди.

4. Classmap срещу PSR-0 срещу PSR-4

Всички те са различни начини за картографиране на пространствата от имена със съответните им пътища, след като изберете един от тях, трябва да следвате техните правила и в крайна сметка композиторът знае как да намери и зареди файла въз основа на картографирането, което следвате .

a) Classmap:е най-простият и най-ясен, той отпечатва логиката в vendor/composer/autoload_classmap.php, когато композиторът прочете, че използваме автоматично зареждане classmap, той сканира всички файлове в споменатите директории (във файл composer.json) и създайте масив от пространства от имена и съответните пътища.

Забележка: добавянето на нови файлове изисква composer dumpautoload за повторно генериране на картографирането.

b) PSR-0: логиката съществува в vendor/composer/autoload_namespaces.php и - от името й - следва правилата на PSR-0.

c) PSR-4: логиката съществува в vendor/composer/autoload_psr4.php и - от името й - следва правилата на PSR-4.

И PSR-0 и PSR-4 имат почти едни и същи правила.

Обърнете внимание на следното:

  • И за двете не е нужно да изпълнявате composer dumpautoload всеки път, когато добавяте нов PHP клас, тъй като процесът на „търсене на пътя на файла“ протича динамично.
  • Трябва да използвате пространства от имена, особено с PSR-4, защото пространството от имена е прикачено към пътя на файла.

Името на поддиректорията ТРЯБВА да съответства на регистъра на имената на подпространствата от имена. -PSR-4

  • PSR-0 преобразува долната черта в разделител на директория и не го прави в PSR-4:

Всеки _ символ в ИМЕТО НА КЛАСА се преобразува в
DIRECTORY_SEPARATOR. Знакът _ няма специално значение в пространството от имена
. -PSR-0

Така $a = new Classes_A(); ще зареди следния файл:

<?php
// path /Classes/A.php
class Classes_A {}

Забележете тук, че не използваме пространства от имена.

  • Следният composer.json работи според очакванията и всеки префикс на пространството от имена App ще търси файла в директорията Classes, но с psr-0 ще го намерите объркващо и няма да работи според очакванията:
{
  "autoload": {
    "psr-4": {
      "App\\" : "Classes"
    }
  }
}

5. Заключение

Започнахме да дефинираме автоматичното зареждане в PHP и проблема, който решава, след това изградихме нашия прост и накрая преминахме към разговор за композитора и как прави картографирането по различни начини.

Основната причина, поради която въведох тази тема, е, че използваме композитор в повечето от нашите приложения и пакети и трябва да разберем как работи разделът autoload.

Опитах се да го опростя, доколкото мога, можете да отидете по-далеч с връзките по-долу и ако имате някакъв въпрос, просто го оставете в коментар.

6. Използвана литература

  1. http://php.net/manual/en/language.oop5.autoload.php
  2. http://php.net/manual/en/function.spl-autoload-register.php
  3. http://php.net/manual/en/function.get-included-files.php
  4. https://getcomposer.org/doc/04-schema.md#autoload
  5. https://www.php-fig.org/psr/psr-0
  6. https://www.php-fig.org/psr/psr-4