ข้อผิดพลาดร้ายแรงของ PHP: ไม่สามารถประกาศคลาสซ้ำได้


162

ไม่มีใครรู้ว่าสิ่งที่สามารถทำให้เกิดปัญหานี้หรือไม่?

ข้อผิดพลาดร้ายแรงของ PHP: ไม่สามารถประกาศคลาสซ้ำได้


11
สิ่งนี้สามารถผนวกเข้ากับ APC + autload ดูstackoverflow.com/questions/4575341/…
gagarine

5
ใช้ autoload หรือคุณสามารถลองได้if(!class_exists('YourClass')){ include 'YourClass.php'; }
Timo Huovinen

คำตอบ:


117

หมายความว่าคุณได้สร้างคลาสแล้ว

ตัวอย่างเช่น

class Foo {}

// some code here

class Foo {}

ฟูที่สองนั้นก็จะโยนความผิดพลาดนั้น


75
คำตอบนี้ไม่เป็นประโยชน์เท่าของ AaronLS ฉันไม่คิดว่าผู้ถามจะถามคำถามว่าเขาเขียนข้อความซ้ำ ๆ แบบนี้อย่างชัดเจน (แม้ในสถานการณ์ที่ค่อนข้างซับซ้อน) ส่วนปลาย include_once ช่วยอธิบายคุณสมบัติที่ชัดเจนของ PHP
DavidHyogo

2
ข้อผิดพลาดนี้อาจเกิดขึ้นหากคุณกำหนดวิธีการ __ โครงสร้างมากกว่าหนึ่งครั้ง
Jack Trowbridge

4
เพียงใช้ include_once ('FooBar.php') เพื่อรวมคลาสของคุณ ชื่อของฟังก์ชันอธิบายตนเอง
Marco Matarazzi

2
คำตอบ AaronLS ถูกจัดอยู่ในอันดับที่สูงขึ้นมากและคุณสามารถค้นหาได้ทางลงที่นี่
qris

1
ที่จริงแล้วสิ่งนี้ตอบคำถามได้อย่างสมบูรณ์แบบและไร้กาลเวลา AaronLS ตั้งสมมติฐานแล้วพยายามแก้ไขปัญหาที่สามารถแก้ไขได้ด้วยวิธีที่ดีกว่ามากมาย
TarranJones

317

คุณมีคลาสชื่อเดียวกันที่ประกาศมากกว่าหนึ่งครั้ง อาจรวมถึงหลาย ๆ เมื่อรวมไฟล์อื่น ๆ คุณต้องใช้สิ่งที่ต้องการ

include_once "something.php";

เพื่อป้องกันการรวมหลายรายการ มันง่ายมากที่จะเกิดขึ้น แต่ไม่ชัดเจนเสมอไปเนื่องจากคุณอาจมีไฟล์ที่มีความยาวรวมกัน


10
นี่มันช่วยได้เต็มที่จริงๆ!
Marci-man

4
หลีกเลี่ยงการ include_onceก็ช้าใช้อย่างอื่นแทนเช่นautoloading :)
Timo Huovinen

21
@Timo ตามมาตรฐานที่ฉันเคยดูจะมีความแตกต่างที่เห็นได้ชัดเจนประมาณ 1 วินาทีหากคุณมีไฟล์ที่มี คุณจะดีกว่าการเพิ่มประสิทธิภาพการเข้าถึงฐานข้อมูลหรือตรรกะอื่น ๆ ของคุณดีกว่าการเพิ่มประสิทธิภาพไฟล์ก่อนกำหนดของคุณรวมถึงการใช้เทคนิคต่ำกว่ามาตรฐานเช่นไฟล์ต้นแบบรวม คุณลักษณะ autoload ไม่ทำงานแตกต่างกันมาก แต่ละฟังก์ชั่นแตกต่างกันและไม่เหมาะสม คุณสามารถใช้อันหนึ่งกับอีกอันหนึ่งได้ แต่มีมุมตัวเรือนที่ไม่ทำงานเหมือนกัน
AaronLS

3
@Timo หากต้องการอ้างอิงหน้าเว็บที่คุณเชื่อมโยง "โดยใช้ __autoload () จะไม่สนับสนุนและอาจเลิกใช้หรือลบออกในอนาคต"
AaronLS

1
@AaronLS ไม่สามารถแก้ไขความคิดเห็นเกี่ยวกับ SO, การเชื่อมโยงไปยังเชื่อมโยงกับตัวอย่างที่ดี ฉันแนะนำมันหลังจากที่ได้อ่านความคิดเห็นของนักพัฒนาของ APC และวิธีที่เขาเกลียด include_once (ฉันรู้สึกแย่กับเขา) ความแตกต่างนั้นเป็นมากกว่าแค่ประสิทธิภาพ
Timo Huovinen

55

ที่เกิดขึ้นเมื่อคุณประกาศคลาสมากกว่าหนึ่งครั้งในเพจ คุณสามารถแก้ไขได้โดยการห่อทั้งที่เรียนกับถ้างบ (เช่นด้านล่าง) หรือคุณสามารถใส่ลงในแฟ้มแยกต่างหากและการใช้งานแทนrequire_once()include()

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

5
It's class_exists ('TestClass') === false หรือ! class_exist ('TestClass')
Jens A. Koch

2
ใน @ Jens-AndréKochแสดงความคิดเห็นว่า "s" หายไปในตัวอย่างที่สอง -> It's class_exists('TestClass') === falseor!class_exists('TestClass')
furins

จริง ขอบคุณสำหรับการชี้ให้เห็นว่า ไม่สามารถแก้ไขได้อีกต่อไป .. หมดเวลา
Jens A. Koch

ขอบคุณสำหรับตรรกะนี้
แฟรงค์

21

ใช้include_once();- ด้วยสิ่งนี้รหัสของคุณจะถูกรวมเพียงครั้งเดียว


15

สิ่งนี้จะเกิดขึ้นถ้าเราใช้คลาสใด ๆ ที่สร้างขึ้นในไลบรารี php ฉันใช้ชื่อคลาสเป็นไดเรกทอรีและฉันได้รับข้อผิดพลาดเดียวกัน หากคุณได้รับข้อผิดพลาดก่อนตรวจสอบให้แน่ใจว่าชื่อคลาสที่คุณใช้ไม่ใช่หนึ่งในคลาสที่สร้างขึ้น


คำตอบทองคำที่นี่สำหรับฉัน - ฉันไม่คิดว่า PHP อาจมีชื่อคลาสเดียวกันกับที่ฉันใช้อยู่!
Jamie M

12

ข้อผิดพลาดนี้อาจเกิดขึ้นหากคุณกำหนด__constructวิธีการมากกว่าหนึ่งครั้ง


2
นี่ควรเป็นความเห็นเกี่ยวกับคำตอบที่ยอมรับแล้วและมีผู้โหวตสูงมาก
Yaroslav

8

บางครั้งเกิดขึ้นเนื่องจากข้อบกพร่องบางอย่างใน PHP ของ FastCGI

ลองรีสตาร์ท ที่ Ubuntu คือ:

service php-fastcgi restart

ตกลงมันเป็นวิธีการแก้ปัญหา แต่ไม่สามารถแก้ไขปัญหาได้และในกรณีของฉันปัญหาจะปรากฏขึ้นแบบสุ่มหนึ่งหรือสองครั้งต่อเดือน :(
SkaJess

@SkaJess - คุณสามารถเพิ่มคำสั่งรีสตาร์ทเพื่อ crontab เพื่อเริ่มต้นใหม่ทุกชั่วโมง สกปรก - แต่จะรับประกันได้ว่าการหยุดทำงานเว็บไซต์ของคุณจะสูงสุด 1 ชั่วโมง
luchaninov

@ วิธี - มันไม่ใช่วิธีที่ดีสำหรับฉันเพราะ php ล้มลงในระหว่างวันทำงาน ฉันคิดว่าวิธีหนึ่งที่ฉันจะเพิ่มคำสั่งเริ่มต้นใหม่ทุกวันในช่วงกลางคืน ในวิธีที่สองฉันจะพิจารณาอัพเกรด IIS และ PHP
SkaJess

6

ฉันมีปัญหาเดียวกันในขณะที่ใช้autoloadดังนี้:

<?php

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


__autoload("MyClass1");

$obj = new MyClass1();

?>

และในชั้นเรียนอื่น ๆ มี:

namespace testClassNamespace;


class MyClass1
{

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

วิธีแก้ปัญหาคือการรักษาความเข้ากันได้ของเนมสเปซในตัวอย่างของฉันnamespace testClassNamespace;ในไฟล์ทั้งสอง


3

เพิ่งเพิ่ม;

ข้อผิดพลาดนี้ยังสามารถเกิดขึ้นได้หากคุณใส่ฟังก์ชันภายในฟังก์ชันอื่นโดยไม่ได้ตั้งใจ


3

PHP 5.3 (ฉันคิดว่ารุ่นเก่าเกินไป) ดูเหมือนว่าจะมีปัญหากับชื่อเดียวกันในกรณีที่แตกต่างกัน ดังนั้นฉันจึงมีปัญหานี้เมื่อมีการเข้าสู่ชั้นเรียนและอินเทอร์เฟซมันใช้เข้าสู่ระบบ หลังจากฉันเปลี่ยนชื่อ LogIn เป็น Log_In ปัญหาได้รับการแก้ไข


3

เพียงแค่ทำสิ่งหนึ่งเมื่อใดก็ตามที่คุณรวมหรือต้องการชื่อไฟล์คือ class.login.php คุณสามารถรวมวิธีนี้ได้:

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

ด้วยวิธีนี้มันไม่เคยเกิดข้อผิดพลาด


2

ฟังก์ชั่นนี้จะพิมพ์สแต็คบอกคุณว่ามันถูกเรียกจาก:

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

เรียกใช้ฟังก์ชันนี้ที่ด้านบนของไฟล์ที่มีคลาสของคุณ

บางครั้งมันจะพิมพ์เพียงครั้งเดียวแม้ว่าชั้นเรียนของคุณจะถูกรวมสองครั้งหรือมากกว่า เนื่องจาก PHP แยกวิเคราะห์คลาสระดับบนทั้งหมดในไฟล์ก่อนเรียกใช้โค้ดใด ๆ และส่งข้อผิดพลาดร้ายแรงทันที ในการแก้ไขปัญหานี้ให้ห่อประกาศของชั้นในif(true) { ... }ซึ่งจะทำให้ชั้นเรียนของคุณเลื่อนระดับลงในขอบเขต จากนั้นคุณควรได้รับสองร่องรอยก่อนที่ PHP จะเกิดข้อผิดพลาดร้ายแรง

สิ่งนี้จะช่วยให้คุณค้นหาว่าคุณรวมคลาสที่ใดจากโครงการที่ซับซ้อน


1

คุณใช้ Zend Framework หรือไม่ ฉันมีปัญหาเดียวกันด้วย
ฉันแก้ไขมันโดยการคอมเม้นต์บรรทัดต่อไปนี้ในconfig/application.ini:

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

ฉันหวังว่านี่จะช่วยคุณได้


1

ผู้ร้ายที่เป็นไปได้อีกอย่างหนึ่งคือการควบคุมแหล่งที่มาและความขัดแย้งที่ไม่ได้รับการแก้ไข SVN อาจทำให้คลาสเดียวกันปรากฏสองครั้งในไฟล์รหัสที่ขัดแย้ง รุ่นทางเลือกสองแบบ ("ของฉัน" และ "ของพวกเขา")


1

ฉันพบว่าปัญหาเดียวกัน: เวอร์ชัน php ที่ใหม่กว่าไม่ได้จัดการเหมือนกันกับการรวมไฟล์หลาย ๆ ไฟล์ (เป็นไลบรารี่) ดังนั้นตอนนี้ฉันต้องเปลี่ยนทั้งหมดของฉันโดยบางอย่างรวมถึง include_once

หรือเทคนิคนี้อาจช่วยได้ถ้าคุณไม่มีคลาสในห้องสมุดมากเกินไป ...

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

1

ฉันมีปัญหาเดียวกัน "ข้อผิดพลาดร้ายแรงของ PHP: ไม่สามารถประกาศคลาส XYZ.php ซ้ำได้"

ฉันมีสองไดเรกทอรีที่ชอบcontrollerและmodelฉันอัปโหลดโดย XYZ.php ในทั้งสองไดเรกทอรีโดยไม่ตั้งใจ (ดังนั้นไฟล์ที่มีชื่อเดียวกันจะทำให้เกิดปัญหา)

วิธีแก้ปัญหาแรก:

ค้นหาในโครงการทั้งหมดของคุณและตรวจสอบให้แน่ใจว่าคุณมีคลาส XYZ.php เพียงคลาสเดียวเท่านั้น

ทางออกที่สอง:

เพิ่มเนมสเปซในคลาสของคุณเพื่อให้คุณสามารถใช้ชื่อคลาสเดียวกันได้


0

ฉันพบปัญหาเดียวกันแล้ว พบกรณีที่เป็นชื่อชั้น ฉันจัดการกับมันโดยเปลี่ยนชื่อ ดังนั้นการแก้ไขปัญหา


0

หมายถึงคลาสนั้นมีการประกาศในหน้าแล้วและคุณพยายามสร้างมันขึ้นมาใหม่

เทคนิคง่าย ๆ ดังต่อไปนี้

ฉันแก้ไขปัญหาดังต่อไปนี้ หวังว่าสิ่งนี้จะช่วยคุณได้เล็กน้อย

if(!class_exists("testClassIfExist"))
{
    require_once("testClassIfExist.php");
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.