แนวทางปฏิบัติที่ดีที่สุดสำหรับห้องสมุดระดับ PHP ที่เป็นบุคคลที่สาม


17

ขณะนี้ฉันกำลังทำงานกับโมดูลที่ต้องใช้ไลบรารี PHP ของบุคคลที่สามซึ่งเป็นชั้น PHP เดียว โดยปกติฉันจะวางไว้ในรวม / ไดเรกทอรีย่อยและเพิ่ม

files[] = includes/Foo.php

ไปยังแฟ้ม .info ของฉันและให้อัตโนมัติระดับ Drupal 7 $foo = new Foo()รถตักดินทำสิ่งที่ตนเมื่อฉันทำ

อย่างไรก็ตามฉันได้รับอนุญาตให้เผยแพร่โมดูลนี้สู่สาธารณะและไม่ต้องการรวมไลบรารีเข้ากับโมดูล ฉันตระหนักดีถึงความยุ่งยากเกี่ยวกับการออกใบอนุญาต แต่เพื่อคำถามนี้ฉันอยากจะเพิกเฉย

มีคำถามที่คล้ายกันฉันจะรวมห้องสมุด PHP ได้อย่างไร แต่ฉันไม่คิดว่าสิ่งนี้จะตอบปัญหาของฉันได้

คำตอบสำหรับคำถามนี้โดยพื้นฐานแล้วบอกว่าจะใช้Libraries APIแต่ทุกโมดูลเดียวที่ฉันพบว่าใช้สิ่งนี้เพียงทำlibraries_get_path()เพื่อรับ basepath (และรวมถึงเส้นทางทางเลือกเมื่อไม่พร้อมใช้งาน) จากนั้นทำอย่างใดอย่างหนึ่งrequireหรือincludeกับบางส่วน การตรวจสอบข้อผิดพลาด (หรือไม่) ทุกคนทำสิ่งที่ชอบ:

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

ในกรณีนี้ Libraries API ไม่ได้ทำอะไรจริงๆ ฉันไม่เห็นข้อได้เปรียบในการใช้สิ่งนี้มากกว่าวิธีเก่า ๆ ที่ขอให้ผู้ใช้ดาวน์โหลดสำเนาและวางไว้ในโฟลเดอร์โมดูลเอง และยังคงมีปัญหาที่นักพัฒนาโมดูลยังคงต้องการที่จะตนเองทำโหลดด้วย/include requireตัวอย่างเช่นโมดูล Facebook เพิ่งโหลดไลบรารีในhook_initและโมดูลตัวกรอง HTML มีฟังก์ชันภายในเพื่อตรวจสอบและโหลดทุกครั้งที่ต้องการไลบรารี

นี่อาจเป็นการฝึกฝนที่แพร่หลายแต่ก็ไม่ได้เป็นแนวปฏิบัติที่ดีที่สุด

โมดูลของฉันควรใช้ความคิดริเริ่มและประกาศสิ่งที่hook_libraries_infoฉันสามารถใช้ได้libraries_load('foo')หรือไม่? นี่ก็เหมือนกัน


ปัญหาอีกประการคือใบขับขี่ของห้องสมุดบุคคลที่สามนั้นตรงกับของ drupal หรือไม่ ถ้าเป็นเช่นนั้นและมันไม่ใหญ่มากฉันจะรวมมันไว้ด้วย หากไม่เป็นเช่นนั้นคุณจะไม่สามารถ / ไม่ควรรวมไว้ในตอนเริ่มต้นดังนั้นวิธีการในห้องสมุดจึงดูดีขึ้นและให้ผู้ใช้ปลายทางดาวน์โหลดเอง
Jimajamma

จุดประสงค์หนึ่งของif (libraries_load($name)) {..}คือเพื่อหลีกเลี่ยง WSOD ในกรณีที่ไม่มีไลบรารี
donquixote

คำตอบ:


7

Branch 2.x ของโมดูล Libraries API ช่วยให้นักพัฒนาสามารถกำหนดผ่านhook_l ไลบรารี_info ()หรือไฟล์. info สำหรับไลบรารีข้อมูลต่อไปนี้ (ดูที่Libraries.api ):

  • การพึ่งพาของห้องสมุด
  • เวอร์ชันที่ไลบรารีเข้ากันได้สำหรับการอ้างอิงแต่ละรายการ
  • รายการไฟล์ที่ต้องโหลด (ไฟล์ CSS, JavaScript หรือ PHP)

รายการไฟล์ที่ต้องโหลดจะใช้ในการโหลดไฟล์เหล่านั้นเมื่อจำเป็นต้องใช้ไลบรารี ซึ่งหมายความว่าโมดูลของคุณไม่จำเป็นต้องโหลด CSS และไฟล์ JavaScript ด้วยdrupal_add_css()หรือdrupal_add_js()อย่างที่ทำไว้แล้วจากโมดูลไลบรารี API การโหลดการพึ่งพาเป็นงานที่ทำจากโมดูล Libraries API โดยไม่ต้องมีโมดูลการโทรทำอะไร

โมดูลทั้งหมดจะใช้รหัสต่อไปนี้สำหรับการโหลดห้องสมุด (ดูที่การใช้ Libraries API 2.x (ในฐานะผู้พัฒนาโมดูล) )

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

หากคุณต้องการตรวจสอบว่ามีห้องสมุดอยู่หรือไม่โมดูลควรใช้รหัสที่คล้ายกับห้องสมุดต่อไปนี้

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

ระหว่างคุณสมบัติhook_libraries_info()สามารถส่งคืนได้ยังมี'download url'ซึ่งไม่ได้ใช้จริงแม้แต่ในสาขา 3.x อาจเป็นไปได้ว่ามันจะถูกใช้ในอนาคตหรือโมดูลของบุคคลที่สามสามารถเชื่อมต่อเข้ากับโมดูลไลบรารี API และดาวน์โหลดไลบรารีที่ร้องขอ แต่หายไป


คุณสามารถชี้ให้เห็นโมดูลยอดนิยมใด ๆ ที่ทำกับไลบรารี PHP ได้หรือไม่? ส่วนหนึ่งของแรงจูงใจสำหรับคำถามคือเพื่อให้ฉันสามารถปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดสำหรับโมดูลสาธารณะดังนั้นฉันจึงเริ่มค้นหาผู้ที่ใช้ไลบรารี API ฉันไม่พบใด ๆ ที่ใช้งาน hook_l ไลบรารี_info () และใช้ Libraries_load () ภายใน
mpdonadio

โมดูล zencorderapi (ส่วนหนึ่งของโมดูลวิดีโอ) ใช้ hook_l ไลบรารี_info ()
AyeshK


@ kiamlaluno ขอบคุณนั่นคือที่แรกที่ฉันดู ในหกห้องสมุดเหล่านั้นมีเพียงสองแห่งเท่านั้นที่ใช้ hook_l ไลบรารี_info ฉันไม่คิดว่าคำตอบของคุณผิด แต่ฉันไม่เชื่อว่านี่เป็นวิธีปฏิบัติที่ดีที่สุดที่แพร่หลายในขณะนี้ ห้องสมุดแห่งหนึ่งมีเทคนิคที่น่าสนใจที่ฉันจะทดสอบและอาจจะโพสต์ในภายหลัง
mpdonadio

@MPD เวอร์ชัน 7.x-2.0 วางจำหน่ายวันที่ 29 กรกฎาคม เป็นไปได้ว่าโมดูลส่วนใหญ่ยังคงใช้วิธี 7.x-1
kiamlaluno

5

หลังจากการขุดในปริมาณที่เหมาะสมฉันก็ยังไม่มั่นใจเกี่ยวกับวิธีปฏิบัติที่ดีที่สุด แรงบันดาลใจจากโมดูลPHPMailerฉันเสนอสิ่งนี้สำหรับห้องสมุด PHP ที่ใช้ในระดับ:

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,
    );
  }
}

สิ่งนี้ใช้hook_registry_files_alterเพื่อตรวจสอบการมีอยู่ของคลาสและหากไม่พบให้เพิ่มไฟล์ลงในคลาสรีจิสตรี (เทียบเท่ากับfiles[] = ...บรรทัดในไฟล์โมดูล. info) จากนั้นคลาสที่กำหนดใน foo.php จะพร้อมใช้งานกับโปรแกรมโหลดอัตโนมัติดังนั้นจึงไม่จำเป็นต้องโหลดไฟล์อย่างชัดเจนก่อนที่จะใช้คลาส

สิ่งนี้จะสร้างข้อกำหนดที่อ่อนนุ่มบน Libraries API และจะใช้ถ้ามีมิฉะนั้นให้ใช้ค่าเริ่มต้นที่สมเหตุสมผล

การเพิ่มการตรวจสอบบางอย่างผ่านทางhook_requirementsเพื่อให้แน่ใจว่าไฟล์นั้นมีอยู่ว่าตัวโหลดอัตโนมัติพบคลาสการตรวจสอบรุ่น ฯลฯ เป็นความคิดที่ดีเช่นกัน

นอกจากนี้ยังเป็นที่น่าสังเกตว่าแนวทาง Autoload สำหรับ Libraries API กำลังถูกกล่าวถึงในคิวปัญหา


อย่าลืมที่จะล้างแคชของคุณหลังจากการดำเนินการ hook_registry_files_alter มิฉะนั้นจะทริกเกอร์เคยชิน;)
saadlulu

2

กล่าวโดยย่อ: หากคุณวางแผนที่จะเผยแพร่โมดูลสู่สาธารณะและห้องสมุด (บุคคลที่สาม) ไม่ใช่ GPL'd คุณจะต้องใช้ Library เป็นอ้างอิงหรือขอให้ผู้ใช้ดาวน์โหลดไฟล์เหล่านี้ด้วยตนเอง (แต่คุณจะไม่สามารถ autoload จากไฟล์. info)

อีกเล็กน้อย:

เหตุผลที่เราจำเป็นต้องมีโมดูลห้องสมุดก็คือการออกใบอนุญาต ไม่ว่าคุณจะใช้โมดูลนั้นหรือไม่ก็ตามคุณกำลังรวมไฟล์นั้นด้วยวิธีใดวิธีหนึ่ง

ฉันคิดว่าคุณไม่พบตัวอย่างที่ดีสำหรับกรณีที่จัดส่งมาพร้อมกับโมดูล ตรวจสอบโมดูล SMTPและมาพร้อมกับคลาสที่จำเป็นตามที่อยู่ใน GPL ( .info ไฟล์ blob )

ยังเห็นโมดูลsimplehtmldomซึ่งเพิ่งรวมไฟล์ แต่ไม่มีอะไรอื่น

โมดูลที่ไหนมีประโยชน์ก็คือคุณสามารถขอให้ผู้ใช้อัปโหลดไฟล์ได้ทุกที่ที่ต้องการ ไม่ชัดเจนว่าผู้ใช้จะอัปโหลดไปยังโฟลเดอร์ไซต์ / ทั้งหมด / ไลบรารี อาจเป็นไซต์ / example.com / libraries หรืออะไรทำนองนั้น โมดูลไลบรารีสามารถช่วยให้คุณมุ่งเน้นไปที่งานจริงของคุณโดยทำสิ่งที่ค้นพบไดเรกทอรีสำหรับคุณ

สำหรับโมดูลที่กำหนดเองที่ฉันพัฒนาสำหรับลูกค้าของฉันฉันมักจะรวมไฟล์ในโฟลเดอร์โมดูลและใช้รายการไฟล์ require_once หรือ. info ขึ้นอยู่กับการใช้ห้องสมุด

นอกจากนี้ปัญหาสิทธิ์ใช้งานไม่ได้เป็นเพียงเหตุผลเดียวในการใช้โมดูล Libraries จะเกิดอะไรขึ้นถ้าไลบรารี่ของบุคคลที่สามมีรอบการเปิดตัวอย่างรวดเร็วและโมดูลของคุณได้รับการพัฒนาน้อยที่สุด? หากคุณรวมไว้ในโมดูลคุณจะต้องทำการเปิดตัวใหม่ทุกครั้ง คุณจะไม่ต้องการมีรุ่น 7.x-1.99 ซึ่งคล้ายกับ 7.x-1.0 ฉันเดา


ขอบคุณที่สละเวลาตอบ ฉันแก้ไขคำถามเพื่อชี้แจง คำถามไม่ได้เกี่ยวกับภาวะแทรกซ้อนของการออกใบอนุญาตและกำหนดเวลาเผยแพร่และวิธีที่ Library API ให้ความช่วยเหลือ ฉันอยากรู้เกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดเกี่ยวกับการโหลดห้องสมุดบุคคลที่สามจริง ๆ
mpdonadio

2

ดูเหมือนว่าปัญหาสำคัญคือการโหลดอัตโนมัติ

คุณสามารถใช้โมดูลไลบรารีพร้อมโมดูลxautoload

จากนั้นในโมดูลของคุณเองคุณทำ

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');
      },
    ),
  );
}

นี่คือรายละเอียดเพิ่มเติมที่นี่:
xautoload.api.php
เพิ่มเติมเกี่ยวกับอาร์กิวเมนต์ $ api

หมายเหตุ: คุณยังสามารถเขียน "เครื่องมือจัดการ" ของคุณเองเพื่อใช้รูปแบบโรงเรียนเก่าที่แปลกใหม่กว่า PSR-0 หรือลูกแพร์ หากคุณต้องการความช่วยเหลือให้โพสต์ปัญหาในคิว xautoload

หมายเหตุ: มีมากกว่าหนึ่งวิธีในการลงทะเบียนเนมสเปซไลบรารีของคุณ อันนี้ง่ายที่สุดถ้าคุณต้องการให้ namespaces ที่จะลงทะเบียนในทุกคำขอ


1
ฉันควรเพิ่มสิ่งนี้ไม่ช่วยในการโหลดไฟล์ขั้นตอน สิ่งนี้จะต้องทำด้วยตนเองทันทีที่คุณต้องการห้องสมุดในการร้องขอ
donquixote

นอกจากนี้บางไลบรารีมีโซลูชันการโหลดคลาสของตนเอง ถึงกระนั้นมันจะสะดวกกว่าในการใช้ตัวโหลดที่มีอยู่แล้วใน Drupal / contrib
donquixote
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.