2010-09-28 18 views
9

Ví dụ:Có cách nào để sử dụng CLASS_EXISTS và __autoload mà không cần CRASH tập lệnh?

ClassName.php

<?php echo "This will crash all"; ?> 

Trong tập tin khác ...

foreach ($FILENAMES_WITHOUT_DOT_PHP as $name => $value) { 
    if (class_exists($value)) { 
     echo "ClassName exists..."; 
    } 
    else { 
     echo "ClassName doesn't exists...."; 
    } 
} 

Kết quả của mã này là: này sẽ sụp đổ tất cả

Thay vào đó của điều này: ClassName doe sn't tồn tại ....

Autoload chức năng:

function __autoload($var_class) 
{ 
    require_once("$var_class.php") ; 
} 
+0

obviusly là cần thiết để sử dụng tự động load bởi vì lớp không được tải! –

+0

Hiển thị chức năng tự động tải của bạn ... Nó sẽ hiển thị 'ClassName không tồn tại ....' sau khi 'Điều này sẽ sụp đổ tất cả', vì nó không quan tâm theo mặc định nếu lớp không được nạp. Tôi nghi ngờ bạn đang giết chết việc thực hiện trong '__autoload' chức năng nếu bạn không tìm thấy các lớp học, và bạn không nên ... – ircmaxell

+0

Từ mã được cho kết quả không thể được sao chép. Vì vậy, đăng một số mã hơn. – tplaner

Trả lời

1

Sử dụng class_exists bên trong hàm autoload thì đừng bao giờ sử dụng nó một lần nữa. Đó là điểm của bộ nạp tự động.

class App { 
    static private $_instance = NULL; 

    public function __construct() { 
     spl_autoload_register('app::autoLoader'); 
    } 

    public function __destruct() { 
    } 

    public static function getInstance() { 
     if(self::$_instance == NULL) { 
      self::$_instance = new App(); 
     } 
     return self::$_instance; 
    } 

    public static function autoLoader($class) { 
     $className = stripslashes($class); 
     if (class_exists($className)) { 
      return; 
     } 
     require $className.'.class.php'; 
    } 
} 
+4

HUH? Không có nó ... Có rất nhiều cách sử dụng cho class_exists. Một trong số đó là để xem liệu lớp đó có thể tải được để bắt đầu (để xem nó có khả dụng hay không). Bên cạnh đó, không có lý do gì để gọi 'class_exists' từ bên trong chức năng tự động tải vì bạn biết nó chưa có (trừ khi ai đó gọi nó theo cách thủ công, nhưng chúng cũng không nên). Oh, và nếu tôi là bạn, tôi sẽ làm một số kiểm tra để xác định xem các tập tin thực sự tồn tại trước khi chỉ cần làm một mù 'require' vào nó. Nếu không, bạn sẽ mất khả năng kiểm tra xem một lớp có thể tải được không (có thể có ích cho các bộ điều hợp, vv) ... – ircmaxell

+0

Trong ví dụ của tôi, tất cả các tệp lớp đều nằm trong cùng một thư mục. Nhưng có, kiểm tra tập tin là một ý tưởng tốt. – AutoSponge

0

Điều gì xảy ra là khá hợp lý. Hàm __autoload của bạn có lẽ chỉ bao gồm ClassName.php, vì vậy nó sẽ thực thi câu lệnh echo mà bạn đã có.

Nếu bạn đang cố gắng quyết định xem có định nghĩa lớp trong tệp hay không, bạn có thể đọc nội dung của tệp (sử dụng file_get_contents hoặc chức năng tương tự) rồi quét các nội dung này cho định nghĩa lớp bằng cụm từ thông dụng hoặc sử dụng token_get_all (xem Determining what classes are defined in a PHP class file).

+0

tốt, làm thế nào để bao gồm ClassName.php mà không thực thi các câu lệnh echo ...... –

+1

Điều đó là không thể, bao gồm cả mã sẽ thực hiện ** bất cứ điều gì ** mà không có trong một hàm hoặc một lớp. Vì vậy, hoặc không bao gồm tệp hoặc đặt các câu lệnh echo bên trong một hàm/lớp. – wimvds

+0

Nhưng tôi không biết liệu tập tin đó sẽ có một lớp hay chỉ là một kịch bản đơn giản bởi vì tôi có một danh sách các tệp, những gì tôi cần làm là biết những tên tệp này là các lớp hay không. –

12

Ok, vì vậy, đây là cách hoạt động bên trong.

Khi bạn cố gắng sử dụng một lớp không tồn tại, nó gọi mỗi một trong các cuộc gọi lại spl_autoload từng cái một cho đến khi lớp tồn tại (và chức năng __autoload là một trong số chúng). Nếu nó không tồn tại ở cuối chuỗi, nó sẽ làm tăng lỗi không tìm thấy lớp.

Khi bạn gọi class_exists mà không có tham số thứ hai (cho biết không cố gắng tải nó nếu nó không tồn tại), nó gọi chuỗi gọi là spl_autoload cho đến khi nó tìm thấy lớp hoặc phương pháp cuối cùng được gọi . Sau đó, nó trả về nếu nó tìm thấy lớp.

Vì vậy, tất cả phụ thuộc vào những gì bạn đang làm trong chức năng tự động tải. Nếu bạn làm điều gì đó như:

function __autoload($class) { 
    $filename = PATH_TO_CLASSES . $class . '.php'; 
    if (!file_exists($class)) { 
     die('Could not find '.$class); 
    } 
    require_once $filename; 
} 

Nó sẽ giết thực thi và nó sẽ không hoạt động như dự định. Thay vào đó, bạn nên làm:

function __autoload($class) { 
    $filename = PATH_TO_CLASSES . $class . '.php'; 
    if (file_exists($class)) { 
     require_once $filename; 
    } 
} 

Đó là tất cả những gì bạn cần làm.

Bây giờ, bạn không muốn tệp được thực thi. Đó là tốt. Có một giải pháp dễ dàng cho điều đó. Không đặt tệp đó vào cùng thư mục với các lớp được tải tự động của bạn. Nó đánh bại mục đích của autoloading.

Giải pháp duy nhất khác là lưu bản đồ tên lớp vào tên tệp và cơ sở tự động tải xuống của bạn. Nếu không nó sẽ luôn luôn thực hiện các tập tin (vì đó là những gì bạn đang yêu cầu nó để làm) ...

10

Việc sử dụng class_exists sẽ tự động tải trình nạp tự động, đó là lý do bạn gặp sự cố của mình. Bạn có thể bỏ qua trình nạp tự động đã đăng ký bằng cách đặt tham số thứ hai thành sai.

class_exists('foo', false) 

From PHP Documentation

+0

Không chắc chắn lý do tại sao điều này đã được giảm giá khi đây là tài liệu thực tế. –

+0

Vì bạn không bỏ qua trình nạp tự động bằng cách đặt tham số thứ hai thành sai. Bạn chỉ cần bỏ qua lỗi được nêu ra nếu SAU rằng lớp vẫn không tải. –

+2

Điều đó không có ý nghĩa gì từ tài liệu. Tại sao họ gọi nó là 'autoload' với một val bool? –

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