Obecnie pracuję nad modułem, który wymaga biblioteki PHP innej firmy, która jest w zasadzie pojedynczą klasą PHP. Zwykle umieszczałbym go w podkatalogu include / i dodaje
files[] = includes/Foo.php
do mojego pliku .info i pozwól, aby auto-moduł ładujący klasy Drupal 7 zrobił to, co robię $foo = new Foo()
.
Mam jednak pozwolenie na upublicznienie tego modułu i wolę nie dołączać biblioteki z modułem. Zdaję sobie sprawę z komplikacji związanych z licencjonowaniem, ale ze względu na to pytanie chciałbym je zignorować.
Podobne pytanie brzmi: jak dołączyć bibliotekę PHP? , ale tak naprawdę nie sądzę, że to odpowiada na mój dylemat.
To odpowiedzi na to pytanie w zasadzie powiedzieć użyć API bibliotek , ale każdy pojedynczy moduł, który znalazłem, że używa tego właśnie robi libraries_get_path()
, aby uzyskać basePath (i zawiera ścieżkę awaryjnej, gdy nie jest dostępny), a następnie robi require
lub include
niektóre sprawdzanie błędów (lub nie). Wszyscy robią coś takiego:
if (!class_exists('Foo')) {
$path = function_exists('libraries_get_path') ?
libraries_get_path('foo') : 'sites/all/libraries/foo';
if (!include($path . '/Foo.php')) {
// handle this error
}
}
W tym przypadku interfejs API bibliotek naprawdę nic nie robi. Nie widzę korzyści z używania tego, w porównaniu ze starą metodą proszenia użytkowników o pobranie kopii i umieszczenie jej w samym folderze modułu. A, jest jeszcze kwestia, że deweloper moduł nadal musi ręcznie zrobić obciążenie z include
/require
. Na przykład moduł Facebooka po prostu ładuje bibliotekę do hook_init
a moduł HTML Purifier ma wewnętrzną funkcję sprawdzania i ładowania za każdym razem, gdy biblioteka jest potrzebna.
Może to być powszechna praktyka, ale nie wydaje się najlepsza praktyką.
Czy mój moduł powinien przejąć inicjatywę i zadeklarować hook_libraries_info
, żebym mógł z niej skorzystać libraries_load('foo')
? To też wydaje się dziwne.
if (libraries_load($name)) {..}
jest uniknięcie WSOD w przypadku braku biblioteki.Odpowiedzi:
Oddział 2.x modułu API bibliotek umożliwia programistom zdefiniowanie, za pomocą hook_libraries_info () lub pliku .info dla biblioteki, następujących informacji (patrz libraries.api ):
Lista plików, które należy załadować, służy do ładowania tych plików, gdy wymagana jest biblioteka. Oznacza to, że moduł nie musi ładować plików CSS i JavaScript za pomocą
drupal_add_css()
, lubdrupal_add_js()
, jak to już zrobiono z modułu API bibliotek. Ładowanie zależności jest zadaniem wykonywanym z modułu API bibliotek, bez wykonywania modułu wywołującego.Wszystko, co robi moduł, to użycie następującego kodu do załadowania biblioteki. (Zobacz Korzystanie z bibliotek API 2.x (jako programista modułów) .)
Jeśli chcesz tylko wykryć obecność biblioteki, moduł powinien użyć kodu podobnego do następującego.
Pomiędzy właściwościami
hook_libraries_info()
można zwrócić, jest też to'download url'
, co nie jest faktycznie używane, nawet w gałęzi 3.x. Prawdopodobnie będzie on używany w przyszłości lub moduły innych firm mogłyby podłączyć się do modułu API bibliotek i pobierać biblioteki, które są wymagane, ale których brakuje.źródło
Po przyzwoitej ilości kopania wciąż nie jestem przekonany co do najlepszych praktyk. Zainspirowany modułem PHPMailer , oferuję to dla klasowych bibliotek PHP:
Używa hook_registry_files_alter do sprawdzenia istnienia klasy, a jeśli nie zostanie znaleziony, dodaj plik do rejestru klas (odpowiednik
files[] = ...
linii w pliku .info modułów). Następnie klasy zdefiniowane w foo.php będą dostępne z autoloaderem, więc nie ma potrzeby jawnego ładowania pliku przed użyciem klasy.Spowoduje to również miękkie wymaganie dotyczące interfejsu API bibliotek i będzie go używać, jeśli jest dostępne, w przeciwnym razie należy zastosować rozsądną wartość domyślną.
Dobrym pomysłem jest również dodanie niektórych sprawdzeń za pomocą hook_requirements, aby upewnić się, że plik istnieje, że autoloader znajdzie klasę, sprawdzenie wersji itp.
Warto również zauważyć, że w kolejce problemów dyskutowane jest podejście do automatycznego ładowania interfejsu API bibliotek .
źródło
Krótko mówiąc: jeśli planujesz udostępnić moduł publicznie, a biblioteka (strony trzeciej) nie jest objęta licencją GPL, będziesz musiał użyć bibliotek jako zależności lub poprosić użytkowników o ręczne pobranie tych plików (ale nie będziesz w stanie załaduj go automatycznie z pliku .info)
W trochę dłużej:
Powodem, dla którego potrzebujemy modułu Biblioteki, jest w zasadzie licencjonowanie. Bez względu na to, czy używasz tego modułu, czy nie, w jakiś sposób dołączasz ten plik.
Cóż, myślę, że nie znalazłeś dobrych przykładów dla takich bibliotek dostarczanych z modułem. Sprawdź moduł SMTP i zawiera niezbędne klasy, takie jak w GPL. ( Kropla pliku .info ).
Zobacz także moduł simplehtmldom , który po prostu zawiera plik, ale nic więcej.
Tam, gdzie przydatny jest moduł Biblioteki, możesz poprosić użytkowników o przesłanie pliku w dowolnym miejscu. Nie jest oczywiste, że użytkownicy prześlą go do folderu witryn / wszystkich / bibliotek. Mogą to być strony / example.com / biblioteki lub coś w tym rodzaju. Moduł Biblioteki może pomóc Ci skoncentrować się na faktycznej pracy, wykonując czynności związane z odnajdywaniem katalogów.
W przypadku niestandardowych modułów, które opracowuję dla moich klientów, zwykle umieszczam pliki w folderze modułów i używam wpisu wymaganego pliku lub pliku .info w zależności od wykorzystania biblioteki.
Ponadto problemy z licencjonowaniem nie są jedynym powodem korzystania z modułu Biblioteki. Co się stanie, jeśli biblioteka strony trzeciej ma szybkie cykle wydawania, a moduł jest minimalnie rozwijany? Jeśli umieścisz go w module, będziesz musiał za każdym razem tworzyć nowe wydanie. Nie będziesz chciał mieć wersji 7.x-1.99, która wydaje się podobna do wersji 7.x-1.0.
źródło
Wydaje się, że głównym problemem jest automatyczne ładowanie.
Możesz użyć modułu bibliotek plus modułu xautoload .
Następnie we własnym module
Wyjaśniono to bardziej szczegółowo tutaj:
xautoload.api.php
Więcej informacji na temat argumentu $ api.
Uwaga: Możesz także pisać własne „moduły obsługi”, aby wdrażać bardziej egzotyczne wzorce oldschoolowe poza PSR-0 lub PEAR. Jeśli potrzebujesz pomocy, opublikuj problem w kolejce xautoload.
Uwaga: Istnieje więcej niż jeden sposób zarejestrowania przestrzeni nazw biblioteki. Ten jest najłatwiejszy, jeśli chcesz, aby przestrzenie nazw były rejestrowane w każdym żądaniu.
źródło