Üçüncü taraf PHP sınıfı tabanlı kitaplık için en iyi uygulama


17

Şu anda temelde tek bir PHP sınıfı olan bir üçüncü taraf PHP kütüphanesi gerektiren bir modül üzerinde çalışıyorum. Normalde, bunu bir include / alt dizinine yerleştirir ve

files[] = includes/Foo.php

.info dosyama ve Drupal 7 sınıfı otomatik yükleyicinin bir şeyi yaptığımda yapmasına izin verin $foo = new Foo().

Yine de, bu modülü halka yayınlama iznim var ve modülün bulunduğu kütüphaneyi içermez. Lisanslama ile ilgili komplikasyonların farkındayım, ancak bu soru uğruna bunu göz ardı etmek istiyorum.

Benzer bir soru var, nasıl bir PHP kütüphanesi eklerim? , ama bunun benim dilime cevap verdiğini sanmıyorum.

Bu sorunun cevabı esas olarak Kütüphaneler API'sini kullandığını söyler , ancak bunu kullanan bulduğum her bir modül sadece libraries_get_path()taban yolunu almak için (ve kullanılabilir olmadığında geri dönüş yolunu içerir) ve sonra bir requireveya includebazılarıyla hata denetimi (veya değil). Hepsi şöyle bir şey yapar:

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
  }
}

Bu durumda, Kütüphaneler API'sı gerçekten hiçbir şey yapmaz. Kullanıcıların bir kopyasını indirmelerini ve modül klasörünün içine yerleştirmelerini istemenin eski yönteminde bunu kullanmanın avantajını görmüyorum. Modül geliştiricisinin hala / ile yükü manuel olarak yapması gereken bir sorun var . Örneğin, Facebook modülü kütüphaneyi a'ya yükler ve HTML Arıtma modülünün her kütüphaneye ihtiyaç duyulduğunda kontrol etmek ve yüklemek için dahili bir işlevi vardır.includerequirehook_init

Bu yaygın bir uygulama olabilir, ancak en iyi uygulama gibi görünmüyor .

Modülüm inisiyatif almalı ve hook_libraries_infokullanabilmem için bir ilan etmeli libraries_load('foo')mi? Bu da tuhaf görünüyor.


Başka bir sorun, üçüncü taraf kütüphanesinin lisansının drupal'larla eşleşip eşleşmediğidir. Olursa ve çok büyük değilse, sadece eklerdim. Başlamazsa, başlamak için ekleyemezsiniz / eklememelisiniz, bu nedenle kütüphane yaklaşımı daha iyi görünür ve nihai son kullanıcılarınızın bunu indirmelerini sağlayın.
Jimajamma

Amaçlarından biri if (libraries_load($name)) {..}kütüphanenin mevcut olmaması durumunda WSOD'den kaçınmaktır.
donquixote

Yanıtlar:


7

Kütüphaneler API modülünün Şube 2.x yoluyla, geliştiriciler tanımlamanızı sağlar ) hook_libraries_info ( veya kütüphane için dosyaya .info, aşağıdaki bilgiler (bkz libraries.api ):

  • Kütüphanenin bağımlılıkları
  • Her bağımlılık için kitaplığın uyumlu olduğu sürüm
  • Yüklenmesi gereken dosyaların listesi (CSS, JavaScript veya PHP dosyaları)

Yüklenmesi gereken dosyaların listesi, kütüphane gerektiğinde bu dosyaları yüklemek için kullanılır. Bu, modülünüzün CSS ve JavaScript dosyalarını önceden drupal_add_css()veya drupal_add_js()Libraries API modülünden yapıldığı gibi yüklemesi gerekmediği anlamına gelir . Bağımlılıkları yüklemek, çağıran modül hiçbir şey yapmadan Kitaplıklar API modülünden yapılan bir görevdir.

Tüm modül bir kütüphane yüklemek için aşağıdaki kodu kullanıyor. (Bkz . Kitaplıklar API 2.x'i kullanma (modül geliştirici olarak) .)

// Try to load the library and check if that worked.
if (($library = libraries_load($name)) && !empty($library['loaded'])) {
  // Do something with the library here.
}

Sadece bir kütüphane olup olmadığını tespit etmeniz gerekiyorsa, modül aşağıdakine benzer bir kod kullanmalıdır.

if (($library = libraries_detect($name)) && !empty($library['installed'])) {
  // The library is installed.
}
else {
  $error = $library['error'];
  $error_message = $library['error message'];
}

Özellikler arasında hook_libraries_info()dönebilir, ayrıca 'download url', aslında kullanılmayan, hatta 3.x dalında bile yoktur. Muhtemelen gelecekte kullanılacaktır veya bir üçüncü taraf modülleri Kitaplıklar API modülüne bağlanabilir ve istenen ancak eksik olan kütüphaneleri indirebilir.


PHP kütüphaneleri ile bunu yapan popüler modüllere dikkat çekebilir misiniz? Soru için motivasyonun bir parçası, genel bir modül için en iyi uygulamaları takip edebilmemdi, bu yüzden kütüphaneler API'sini kullananları aramaya başladım. Hook_libraries_info () uygulanan ve dahili libraries_load () kullanılan herhangi bir bulamadık.
mpdonadio

zencorderapi modülü (Video modülünün bir parçası) hook_libraries_info () kullanır
AyeshK


@kiamlaluno, teşekkürler, ilk gördüğüm yerdi. Altı kitaptan sadece iki tanesi hook_libraries_info uygular. Cevabınızın yanlış olduğunu düşünmüyorum, ancak bunun şu anda yaygın bir en iyi uygulama olduğuna ikna olmadım. Kütüphanelerden birinde test edeceğim ve muhtemelen daha sonra yayınlayacağım ilginç bir teknik vardı.
mpdonadio

@MPD Sürüm 7.x-2.0 29 Temmuz'da piyasaya sürüldü; modüllerin çoğunun hala 7.x-1 yaklaşımını kullanması muhtemeldir.
kiamlaluno

5

İyi bir kazma işleminden sonra, en iyi uygulamanın ne olduğu konusunda hala ikna olmadım. PHPMailer modülünden esinlenerek , bunu sınıf tabanlı PHP kütüphaneleri için sunuyorum:

function foo_registry_files_alter (&$files, $modules)
{
  if (!class_exists('Foo')) {
    $library_path = function_exists('libraries_get_path') ?
      libraries_get_path('foo') : 'sites/all/libraries/foo';

    $files[$library_path . '/Foo.php'] = array(
      'module' => 'foo',
      'weight' => 0,
    );
  }
}

Bu, bir sınıfın varlığını kontrol etmek için hook_registry_files_alter kullanır ve bulunmazsa, sınıf kayıt defterine bir dosya ( files[] = ...modüller .info dosyasındaki bir satıra eşdeğer) ekleyin . Daha sonra, foo.php dosyasında tanımlanan sınıflar otomatik yükleyici ile kullanılabilir olacaktır, bu nedenle sınıfı kullanmadan önce dosyayı açıkça yüklemenize gerek yoktur.

Bu ayrıca Kitaplıklar API'sında yumuşak bir gereksinim oluşturur ve varsa kullanır, aksi takdirde makul bir varsayılan değer kullanır.

Dosyanın var olduğundan emin olmak için hook_requirements aracılığıyla bazı kontroller eklemek , otomatik yükleyicinin sınıfı, sürüm kontrolünü vb. Bulması da iyi bir fikirdir.

Ayrıca, Kütüphaneler API'sı için otomatik yükleme yaklaşımının sorun sırasında tartışıldığını .


Hook_registry_files_alter uyguladıktan sonra önbelleğinizi temizlemeyi unutmayın, aksi takdirde tetiklemeyecektir;)
saadlulu

2

Kısacası: Modülü herkese açık olarak yayınlamayı planlıyorsanız ve (üçüncü taraf) kitaplık GPL'd değilse, Kitaplıkları bağımlılık olarak kullanmanız veya kullanıcılardan bu dosyaları manuel olarak indirmelerini istemeniz gerekir (ancak .info dosyasından otomatik yükle)

Kısa bir süre sonra:

Kütüphaneler modülüne ihtiyacımızın nedeni temelde lisanslamadır. Bu modülü kullansanız da kullanmasanız da, o dosyayı bir şekilde dahil edersiniz.

Bence modül örnekleri ile birlikte gelen bu tür kütüphaneler için iyi örnekler bulamadınız. Check out SMTP modülü ve GPL öyle gibi gerekli sınıfları ile birlikte gelir. ( .info dosya blob'u ).

Ayrıca sadece dosyayı içeren, başka bir şey olmayan simplehtmldom modülüne bakın .

Kütüphaneler modülünün kullanışlı olduğu yerlerde, kullanıcılardan dosyayı istedikleri yere yüklemelerini isteyebilirsiniz. Kullanıcıların bunu sites / all / library klasörüne yükleyeceği açık değildir. Siteler / example.com / kütüphaneleri veya bunun gibi bir şey olabilir. Kitaplıklar modülü, sizin için dizin keşifleri yaparak gerçek çalışmanıza odaklanmanıza yardımcı olabilir.

Müşterilerim için geliştirdiğim özel modüller için genellikle modül klasörüne dosyalar ekler ve kitaplığın kullanımına bağlı olarak requir_once veya .info dosya girişini kullanırım.

Ayrıca, Kütüphaneler modülünü kullanmanın tek nedeni lisans sorunları değildir. Üçüncü taraf kütüphanesinin hızlı yayın döngüleri varsa ve modülünüz minimum düzeyde geliştirilmişse ne olur? Modüle eklerseniz, her seferinde yeni bir sürüm yapmanız gerekir. Sanırım 7.x-1.0'a çok benzeyen 7.x-1.99 sürümüne sahip olmak istemeyeceksiniz.


cevaplamak için zaman ayırdığınız için teşekkür ederiz. Açıklığa kavuşturmak için sorumu biraz düzenledim. Soru aslında lisanslama ve yayınlama programlarının komplikasyonları ve Kitaplıklar API'sının buna nasıl yardımcı olduğu ile ilgili değil. Üçüncü taraf kitaplıkların gerçekten yüklenmesi ile ilgili en iyi uygulamaları merak ediyorum.
mpdonadio

2

En büyük sorun otomatik yükleme.

Sen kullanabilirsiniz kütüphaneler modülü artı xautoload modülü.

Sonra kendi modülünüzde,

function mymodule_libraries_info() {

  return array(
    'mymodule-test-lib' => array(
      'name' => 'My test library',
      ..
      'xautoload' => function($api) {
        // Register a namespace with PSR-0 root in <library dir>/lib/
        // Note: $api already knows the library directory.
        // Note: We could omit the 'lib', as this is the default value.
        $api->namespaceRoot('XALib\TestNamespace', 'lib');
      },
    ),
  );
}

Bu, burada daha ayrıntılı olarak açıklanmaktadır:
xautoload.api.php
$ api argümanı hakkında daha fazla bilgi.

Not: PSR-0 veya PEAR'ın ötesinde daha egzotik eski okul kalıpları uygulamak için kendi "işleyicilerinizi" de yazabilirsiniz. Bununla ilgili yardıma ihtiyacınız varsa, xautoload kuyruğuna bir sorun gönderin.

Not: Kütüphane ad alanlarınızı kaydetmenin birden fazla yolu vardır. Ad alanlarının her istekte kaydedilmesini istiyorsanız, bu en kolayıdır.


1
Eklemeliyim ki, bu işlem dosyaları yüklemede yardımcı olmaz. Bu, istekte kütüphaneye ihtiyaç duyduğunuz anda manuel olarak yapılmalıdır.
donquixote

Ayrıca, bazı kütüphanelerin kendi sınıf yükleme çözümleri vardır. Yine de, Drupal / katkıda bulunan bir yükleyiciyi kullanmak daha uygun olabilir.
donquixote
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.