Lỗi nghiêm trọng của PHP: Không thể phân loại lại lớp


162

Có ai biết những gì có thể gây ra vấn đề này?

Lỗi nghiêm trọng của PHP: Không thể phân loại lại lớp


11
Điều này có thể nối thêm với APC + autload, xem stackoverflow.com/questions/4575341/
Khăn

5
Sử dụng tự động tải hoặc bạn cũng có thể thửif(!class_exists('YourClass')){ include 'YourClass.php'; }
Timo Huovinen

Câu trả lời:


117

Nó có nghĩa là bạn đã tạo một lớp.

Ví dụ:

class Foo {}

// some code here

class Foo {}

Foo thứ hai đó sẽ ném lỗi.


75
Câu trả lời này không hữu ích như AaronLS. Tôi không nghĩ người hỏi sẽ hỏi câu hỏi nếu anh ta viết một sự lặp lại rõ ràng như thế này (ngay cả trong một tình huống khá phức tạp). Mẹo include_once giúp làm rõ một tính năng tối nghĩa của PHP.
DavidHyogo

2
Lỗi này cũng có thể xảy ra nếu bạn xác định phương thức __construct nhiều lần.
Jack Trowbridge

4
Chỉ cần sử dụng include_once ('FooBar.php') để bao gồm lớp của bạn. Tên của chức năng là tự giải thích.
Marco Matarazzi

2
Câu trả lời của AaronLS được đánh giá cao hơn nhiều, và bạn có thể tìm thấy nó ở đây .
qris

1
Trên thực tế điều này trả lời câu hỏi một cách hoàn hảo và nó là vô tận, AaronLS đưa ra một giả định sau đó cố gắng giải quyết vấn đề mà giờ đây có thể được giải quyết bằng nhiều cách tốt hơn.
TarranJones

317

Bạn có một lớp cùng tên được khai báo nhiều lần. Có thể thông qua nhiều bao gồm. Khi bao gồm các tệp khác, bạn cần sử dụng một cái gì đó như

include_once "something.php";

để ngăn chặn nhiều vùi. Điều này rất dễ xảy ra, mặc dù không phải lúc nào cũng rõ ràng, vì bạn có thể có một chuỗi dài các tệp được bao gồm bởi nhau.


10
Điều này thực sự giúp đầy đủ!
Marci-man

4
tránh include_once , nó chậm, thay vào đó hãy sử dụng một cái gì đó khác, như tự động tải :)
Timo Huovinen

21
@Timo Dựa trên điểm chuẩn tôi đã xem, sẽ chỉ có sự khác biệt đáng chú ý trong khoảng 1 giây nếu bạn có một tệp có 100.000 tệp bao gồm. Bạn sẽ tốt hơn khi tối ưu hóa quyền truy cập DB hoặc logic khác hơn là tối ưu hóa sớm tệp của bạn bao gồm sử dụng các kỹ thuật không đạt tiêu chuẩn như tệp bao gồm chính. Tính năng tự động tải không hoạt động khác nhau đáng kể. Mỗi chức năng khác nhau, và không thể thay thế cho nhau. Bạn có thể sử dụng cái này cho cái kia, nhưng có những trường hợp góc mà chúng không hoạt động giống nhau.
AaronLS

3
@Timo Để trích dẫn trang bạn đã liên kết "bằng cách sử dụng __autoload () không được khuyến khích và có thể không được chấp nhận hoặc bị xóa trong tương lai."
AaronLS

1
@AaronLS Không thể chỉnh sửa nhận xét về SO, liên kết cũng liên kết đến ví dụ tốt hơn . Tôi đã đề xuất nó sau khi đọc các bình luận của các nhà phát triển của APC và cách anh ấy ghét include_once (tôi cảm thấy tệ cho anh ấy). Ngoài ra sự khác biệt không chỉ là hiệu suất.
Timo Huovinen

55

Điều đó xảy ra khi bạn khai báo một lớp nhiều hơn một lần trong một trang. Bạn có thể sửa nó bằng cách gói lớp đó bằng câu lệnh if (như bên dưới) hoặc bạn có thể đặt nó vào một tệp riêng và sử dụng require_once(), thay vì include().

if (!class_exists('TestClass')) {
   // Put class TestClass here
}

5
đó là class_exists ('TestClass') === false hoặc! class_exist ('TestClass')
Jens A. Koch

2
Trong @ Jens-AndréKoch, một "s" bị thiếu trong ví dụ thứ hai -> nó class_exists('TestClass') === falsehoặc!class_exists('TestClass')
furins

Thật. Cảm ơn đã chỉ ra rằng. Không thể chỉnh sửa được nữa .. hết thời gian.
Jens A. Koch

Cảm ơn logic này.
Frank

21

Sử dụng include_once();- với điều này, mã của bạn sẽ chỉ được bao gồm một lần.


15

Điều này sẽ xảy ra nếu chúng ta sử dụng bất kỳ lớp nào được xây dựng trong thư viện php. Tôi đã sử dụng tên lớp là Thư mục và tôi đã gặp lỗi tương tự. Nếu bạn gặp lỗi trước tiên, hãy đảm bảo rằng tên lớp bạn sử dụng không phải là một trong các lớp được xây dựng.


Câu trả lời vàng ở đây cho tôi - tôi thậm chí không nghĩ rằng PHP có thể có cùng tên lớp như tôi đang sử dụng!
Jamie M

12

Lỗi này cũng có thể xảy ra nếu bạn xác định __constructphương thức nhiều lần.


2
Đây phải là một nhận xét về câu trả lời đã được chấp nhận và được đánh giá cao
Yaroslav

8

Đôi khi điều đó xảy ra do một số lỗi trong FastCGI của PHP.

Hãy thử khởi động lại nó. Tại Ubuntu, nó:

service php-fastcgi restart

Ok, đó là một giải pháp nhưng nó không khắc phục được vấn đề Và trong trường hợp của tôi, vấn đề xuất hiện ngẫu nhiên một hoặc hai lần mỗi tháng. :(
SkaJess

@SkaJess - bạn có thể thêm lệnh khởi động lại vào crontab để khởi động lại hàng giờ. bẩn - nhưng sẽ đảm bảo rằng thời gian chết tối đa của trang web của bạn sẽ là 1 giờ.
luchaninov

@how - đó không phải là một giải pháp tốt cho tôi vì php đang sụp đổ trong ngày làm việc. Tôi nghĩ rằng theo một cách nào đó tôi sẽ thêm lệnh khởi động lại hàng ngày trong đêm. Theo cách thứ hai, tôi sẽ xem xét nâng cấp IIS và PHP.
SkaJess

6

Tôi đã có cùng một vấn đề trong khi sử dụng autoloadnhư sau:

<?php

function __autoload($class_name)
{
    include $class_name . '.php';
}


__autoload("MyClass1");

$obj = new MyClass1();

?>

và trong lớp khác có:

namespace testClassNamespace;


class MyClass1
{

    function  __construct()
    {
        echo "MyClass1 constructor";
    }
}

Cách giải quyết là giữ khả năng tương thích không gian tên, trong ví dụ của tôi namespace testClassNamespace;trong cả hai tệp.


3

Chỉ cần thêm;

Lỗi này cũng có thể xảy ra nếu bạn do nhầm lẫn đặt một chức năng bên trong một chức năng khác.


3

PHP 5.3 (một phiên bản cũ hơn tôi nghĩ) dường như có vấn đề với cùng tên trong các trường hợp khác nhau. Vì vậy, tôi đã gặp vấn đề này khi có lớp Đăng nhập và giao diện mà nó thực hiện Đăng nhập. Sau khi tôi đổi tên LogIn thành Log_In, vấn đề đã được giải quyết.


3

Chỉ cần làm một việc bất cứ khi nào bạn bao gồm hoặc yêu cầu tên tệp là class.login.php. Bạn có thể bao gồm nó theo cách này:

include_once class.login.php or 
require_once class.login.php

Bằng cách này, nó không bao giờ ném một lỗi.


2

Hàm này sẽ in một ngăn xếp cho bạn biết nó được gọi từ đâu:

function PrintTrace() {
    $trace = debug_backtrace();
    echo '<pre>';
    $sb = array();
    foreach($trace as $item) {
        if(isset($item['file'])) {
            $sb[] = htmlspecialchars("$item[file]:$item[line]");
        } else {
            $sb[] = htmlspecialchars("$item[class]:$item[function]");
        }
    }
    echo implode("\n",$sb);
    echo '</pre>';
}

Gọi hàm này ở đầu tệp bao gồm lớp của bạn.

Đôi khi nó sẽ chỉ in một lần, mặc dù lớp của bạn đang được đưa vào hai lần trở lên. Điều này là do PHP thực sự phân tích tất cả các lớp cấp cao nhất trong một tệp trước khi thực thi bất kỳ mã nào và đưa ra lỗi nghiêm trọng ngay lập tức. Để khắc phục điều này, hãy bọc phần khai báo lớp của bạn if(true) { ... }, phần này sẽ chuyển lớp của bạn xuống một mức trong phạm vi. Sau đó, bạn sẽ nhận được hai dấu vết của bạn trước khi lỗi nghiêm trọng của PHP.

Điều này sẽ giúp bạn tìm thấy nơi lớp bạn đang được đưa vào nhiều lần trong một dự án phức tạp.


1

Bạn đã sử dụng Zend Framework? Tôi có cùng một vấn đề quá.
Tôi đã giải quyết nó bằng cách bình luận dòng này sau đây config/application.ini:

;includePaths.library = APPLICATION_PATH "/../library"

Tôi hy vọng điều này sẽ giúp bạn.


1

Một thủ phạm có thể là kiểm soát nguồn và xung đột chưa được giải quyết. SVN có thể khiến cùng một lớp xuất hiện hai lần trong tệp mã bị xung đột; hai phiên bản thay thế của nó ("của tôi" và "của họ").


1

Tôi đã gặp phải vấn đề tương tự: phiên bản php mới hơn không xử lý giống nhau với nhiều tệp của cùng một tệp (dưới dạng thư viện), vì vậy bây giờ tôi phải thay đổi tất cả bao gồm của mình bởi một số include_once.

Hoặc thủ thuật này có thể giúp ích, nếu bạn không có quá nhiều lớp trong thư viện của mình ...

if( class_exists('TestClass') != true )
{
   //your definition of TestClass
}

1

Tôi đã có cùng một vấn đề "Lỗi nghiêm trọng của PHP: Không thể tái phân loại lớp XYZ.php".

Tôi có hai thư mục giống như controllermodeltôi đã tải lên nhầm lẫn XYZ.php trong cả hai thư mục. (Vì vậy, tệp có cùng tên gây ra sự cố).

Giải pháp đầu tiên:

Tìm trong toàn bộ dự án của bạn và đảm bảo rằng bạn chỉ có một lớp XYZ.php.

Giải pháp thứ hai:

Thêm một không gian tên trong lớp của bạn để bạn có thể sử dụng cùng tên lớp.


0

tôi đã gặp vấn đề tương tự phát hiện ra trường hợp là tên lớp. tôi xử lý nó bằng cách thay đổi tên từ đó giải quyết vấn đề.


0

Nó thực sự có nghĩa là lớp đã được khai báo trong trang và bạn đang cố gắng tạo lại nó.

Một kỹ thuật đơn giản là như sau.

Tôi đã giải quyết vấn đề bằng cách sau. Hy vọng điều này sẽ giúp bạn một chút.

if(!class_exists("testClassIfExist"))
{
    require_once("testClassIfExist.php");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.