Search code examples
phpfunctionclasstraitsname-collision

PHP Class Has Colliding Constructor Definitions Coming From Traits


I have 3 files which relate one to another :

class/General.class.php
class/Database.class.php
class/User.class.php

class/General.class.php contains :

trait generalFunctions {

    private $unique_number;
    private $mysql_datetime;
    private $mysql_date;

    function __construct($unique_number, $mysql_datetime, $mysql_date) {
        $this->unique_number = $unique_number;
        $this->mysql_datetime = $mysql_datetime;
        $this->mysql_date = $mysql_date;
    }


    public function encryptData ($data) {
        $unique_number = $this->unique_number;
        $data = $unique_number . $data;
        return $data;
    }

}

class General {
    use generalFunctions;
}

?>

and class/User.class.php basically inherits from Database class :

class User extends Database {
    use generalFunctions;

    public function trialEncrypt ($data) {
    // some code here which need encryptData function from General class
    }
}

When I tried to use these classes :

<?php
include('config.php');
include('class/General.class.php');
include('class/Database.class.php');
include('class/User.class.php');

?>

I got this following error :

Fatal error: User has colliding constructor definitions coming from traits in /home/***/public_html/class/User.class.php on line 178

but when I removed use generalFunctions; from User class, then everything works fine.

Unfortunately, I can't use functions inside General class on User class.

How to solve this problem? I want to have functions inside the General class that can be used by other classes, specially class which extended from other class, such as the User class (extended from the Database class)


Solution

  • Although, it's not posted here, I'm guessing that class/Database.class.php has a constructor in it as well. Since PHP doesn't really do function overloading, there can only be one constructor - you have two, the inherited one from Database and the other from generalFunctions.

    What you'll need to do is alias your trait constructor function with the use statement

    class User extends Database {
        use generalFunctions { 
             generalFunctions::__construct as private traitConstructor; 
        }
    
        public function trialEncrypt ($data) {
        // some code here which need encryptData function from General class
        }
    }
    

    Another Example: How to overload class constructor within traits in PHP >= 5.4

    Also for reference: PHP Traits