2011-09-15 30 views
8

Xin chào, tôi đang phát triển một thư viện cho hợp âm ghita. Trong một số tập tin trên thư viện tôi có một cái gì đó như thế này:Làm cho một thư viện php, làm thế nào để làm cho nó độc lập?

require_once "lib/GuitarChord.php"; 
require_once "lib/Chord.php"; 
require_once "lib/Key.php"; 
require_once "lib/Tuning.php"; 

Làm thế nào tôi có thể làm cho thư viện này vì vậy nó không cần phải biết nơi các tập tin thư viện khác?

Bằng cách này, một người có thể có tệp thư viện trong bất kỳ thư mục nào?

Chỉnh sửa: Đã xóa câu hỏi thứ hai.

+2

Tốt hơn nên đặt một câu hỏi tại một thời điểm và cố gắng giữ cho chúng càng cụ thể càng tốt. – Jon

+0

Có cơ hội để xem thư viện này không? Có phải trên GitHub không? – Gordon

Trả lời

7

Tạo autoloaders cho tất cả các địa điểm nơi các lớp này có thể được.

Ví dụ:

//AUTOLOADER 
function class_autoloader($class) { 

    // presumes classes are in './classes' 
    $folders = array(
    './', './../', './../../' 
    ); 
    $directories = array(
    'classes','lib', '' 
    ); 
    $dir = dirname(__FILE__); 
    $theClass = '/' . $folderedClass . '.php'; 


    foreach($folders as $folder){ 
     foreach($directories as $directory){ 
      $theInclude = $dir.$folder.$directory.$theClass; 

      if (file_exists($theInclude) && include_once($theInclude)) { 
       return TRUE; 
      } 
     } 
    } 

    trigger_error("The class '$class' or the file '$theClass' failed to spl_autoload ", E_USER_WARNING); 

    return FALSE; 
} 

spl_autoload_register('class_autoloader'); 

Sau đó, nếu bạn muốn tải các Chord Class và bạn biết điều đó là trong thư mục lib của bạn, autoloader sẽ làm việc cho bạn khi bạn làm:

new Chord(); 

Bạn có thể đính kèm nhiều lần gọi lại tự động tải lại khác nhau với spl_autoload_register

+0

Có cách nào tôi có thể làm cho thư viện biết nơi các tập tin khác được đặt tự động? Các tệp khác sẽ luôn nằm trên cùng thư mục với điểm nhập thư viện. Ví dụ: yêu cầu "lib/glib.php"; glib là điểm vào. Tất cả các tệp khác được giả định là trên lib /. Điều này có thể không? – carlosdubusm

+0

@carlos - đây là 'tự động' được gọi là' tự động tải ' – Neal

1

Nếu thư viện của bạn sử dụng tất cả hoặc hầu hết các lớp được bao gồm thì hãy cân nhắc đặt tất cả các lớp liên quan đến thư viện của bạn trong cùng một tệp. Các giải pháp khác sẽ chỉ liên quan đến việc thêm nhiều mã hơn, trong trường hợp này bạn có thể chỉ cần sử dụng phương pháp hiện tại của mình.

Nếu bạn muốn chia tệp cho mục đích phát triển thì tất cả vẫn tiếp tục làm như vậy nhưng bạn vẫn có thể gói nó vào một tệp để sử dụng sản xuất để mọi người dễ dàng đưa vào.

+0

Đầu tiên - tôi không downvote, thứ hai - vấn đề của tôi là bạn có thể tải các lớp mà bạn ** không cần ** nếu bạn tạo một tệp lớp ** BIG **, có thể tốt hơn với các tệp nhỏ hơn và một autoloader – Neal

1

Một nơi nào đó bạn sẽ phải bao gồm tên thư mục, nếu bạn không muốn bao gồm tất cả các lớp học của mình trong một tệp. Bạn có thể làm cho nó ở đâu đó mà người dùng chỉ có để thiết lập một lần, mặc dù:

$lib_folder = "lib"; 

require_once $lib_folder . "/GuitarChord.php"; 
require_once $lib_folder . "/Chord.php"; 
require_once $lib_folder . "/Key.php"; 
require_once $lib_folder . "/Tuning.php"; 

Đối với việc xử lý các loại hình cơ sở dữ liệu, bạn có thể thực hiện một khung cảnh như $ db_type mà người dùng một trong hai bộ để "MYSQL", " TẬP_TIN "," XML ", v.v. Và nơi bạn thực hiện cuộc gọi đến db, hãy sử dụng câu lệnh chuyển đổi để xem phương thức cơ sở dữ liệu nào họ đang sử dụng và thay đổi cuộc gọi của bạn cho phù hợp.

Edit: Nó cũng giá trị xem xét PHP's __autoload feature

0

Bạn nên xem namespacesautoloaders.

phép nói rằng bạn có tất cả lớp học của bạn trong không gian tên 'GuitarChords' - vì vậy bạn chỉ có thể tạo autoload chức năng một cái gì đó tương tự như sau (giả sử tập tin, nơi bạn đăng ký autoloader của bạn là trong thư mục cha của "lib"):

spl_autoload_register(function($class){ 
     $namespace = explode('\\', $class, 2); 
      if ($namespace[0] === 'GuitarChords' && isset($namespace[1])) { 
      include(__DIR__.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.$namespace[1].'.class.php'); 
      } 
    }); 

Tôi nghĩ tốt hơn nên đăng ký một chức năng tự động tải cho từng thư viện/bộ/không gian tên cụ thể. Lặp lại các thư mục và sử dụng include_once, file_exists vv có thể tạo ra một số chi phí IO khó chịu tùy thuộc vào độ phức tạp của hệ thống của bạn.

Các vấn đề liên quan