I am including a file with a class GroupManager which is eval'd with IP.content. I have received the error that the class is already defined. If I un-include, I receive no errors. If I rename the class, I receive no errors (however I am certain this class does not exist elsewhere.) I tried the following in case there were multiple includes (I was personally using include_once...):
if( !class_exists('GroupManager') ) {
class GroupManager {
}
}
I still receive the error:
Cannot redeclare class GroupManager in ... GroupManager.php on line 37
Obviously there is no line 37 in my 4-line file.
If I remove the class declaration, and replace it with an echo, I receive no error and it echos fine, which means the class does not exist at that point.
if( !class_exists('GroupManager') ) {
echo "Class does not exist???";
}
I am unsure how to even debug this.
I found the issue, and I should have caught it a lot sooner... Another administrator had included this file in a hook. The hook is apparently run on every page, even though every page does not require the hook... Thus it was not my thought to check the hooks.
If anyone has weird include issues with IPB, make sure you grep for the includes/requires. It'll save you a lot of hassle.
Something like this should give you an idea of where the file is being included:
grep -r include_name.php .
This will check all files recursively from the current dir.
Related
I seem to have some misconceptions on how autoloading works in PHP still, one I simply cannot explain.
I have a class called glue which has a spl_autoload_register within it's main function, here called run like so:
class glue{
public static function run(){
spl_autoload_register(array('glue','autoload'));
}
}
The autoload function works by loading via the PSR-0 standard and works from absolute paths. This is all tested as working etc. Note that glue is not namespaced.
The autoload function covers a namespace called glue. Within this namespace I have a error handler called \glue\ErrorHandler.
When I trigger an error the glue class will autoload \glue\ErrorHandler by PSR-0 notation from the root directory as defined by a stored ROOT constant. This has been tested as working as well in classes such as \glue\User and \glue\Session.
So now for the problem. I cause a Call-time pass-by-reference has been deprecated error within \glue\Validation and it doesn't seem to run my autoload function.
I can see how it is going into my autoload function for everything but when I call this error in that class it just seems to skip my autoloader and bail out saying it can't find my error handler class.
Normally I would say it is something with my programming but I have tried everything. I cannot explain how, for this one error. What compounds my confusion further is that if I cause a:
syntax error, unexpected T_ISSET in /media/server_ws/xxxxxxx/glue/Validation.php on line 47
Error it works. It seems to be for that one error it just will not autoload my error handler.
I thought this might be because my spl_autoload_register is not being binded to that namespace (since the error handler that works is actually called from within glue) and some how, maybe, it is randomly working. So from \glue\Validation I called a class I have never looked at: \glue\util\Crypt but that works and goes into the autoloader correctly.
When I call this error: Call-time pass-by-reference has been deprecated from within glue class it works perfectly.
Can anyone shed some light on this?
Edit
As requested here is a brievated version of Validation.php:
namespace glue;
use glue,
\glue\Exception,
\glue\Collection;
class Validation extends \glue\Component{
private function validateRule($rule){
// This is the line, notice the pass by reference down there?
$valid = $validator($field,$field_value,$params,&$this->model) && $valid;
}
}
The Call-time pass-by-reference has been deprecated error is thrown during script compilation, and auto-loading is disabled during compilation. It's disabled because the compiler cannot start compiling multiple scripts at the same time (i.e. it is not re-entrant), and auto-loading may load some script, which may require compiling it.
Source: https://github.com/php/php-src/blob/76ad52ccc501c02aeb068d2eb4f119ef6f0c2b6a/Zend/zend_execute_API.c#L1058
I know this has been answered before and why this is caused. However, in my case, the problem is happening only on MacOS Lion (10.7) which is on php 5.3.6. The same code base is running on my windows 7 machine which is on php 5.3.8.
I have used require_once all over the place. The code fragment that seems to be causing the problem is:
class DbBase
{
...
}
in a file that is included from multiple files. However the error disappears if I wrap the class declaration inside of:
if (class_exists('DbBase') != true)
{
class DbBase
{
...
}
}
I have this scenario:
File DBBase.php:
defines Class DBBase
File A_DB.php:
require_once("DBBase.php")
File B_DB.php:
require_once("DBBase.php")
File foo.php:
require_once("A_DB.php")
require_once("B_DB.php)
So the file DBBase.php does get included twice. Does it?
Any insight is appreciated.
I was having the same error. However, it wasn't related to 'declare a single class multiple times'. It was because I've made a backup of the class like this:
class.shipping.php
class.shipping_092512_bk.php
Then, I uploaded the backup file to the server. That caused the application to fail due to the two classes. So, I renamed the backup to something else without .php file extension 'class.shipping_092512.bk'. Problem solved.
This error occurs when you declare a single class multiple times instead of once ; The code below would throw that error.
class phpp{}
class phpp{}
It is unlikely that the behaviour is not the same on 5.3.6 and 5.3.8 as there haven't been any significant changes in classes and objects.
You should check for duplicated codes in the files you are requiring once. . .
EDIT :
The require_once() statement is identical to require() except PHP will check if the file has already been included, and if so, not include (require) it again.
So in your case it is not being included multiple times, whereas it would if you use require or include.
However you should restructure your entire code to prevent class redeclaration's.
class lol{}
if(!class_exists("lol")){
class lol{
function ll (){
return "ss";
}
}
}
echo lol::ll();
You wouldnt be able to access that ^^ , since its still a redeclaration.
I have the following error
Fatal error: Cannot redeclare class Database in /home/content/63/8026363/html/include/user_database.php on line 5
That links to the line
class Database
But I have not redeclared this anywhere I can see.
I've checked all the include files and still can't see it.
I have now changed the name to user_database1.php which is DEFINITELY only included once in my WHOLE system and I am still getting the same message!
This only occurs in my root/admin directory.
When I moved the file it occurs into the root directory and updated the include files from ../file.php to just file.php, it worked perfectly.
I can't understand why having the file.php in the /admin directory and using ../ to include files isn't working!
Can anyone offer any experience of this? Or a potential fix.
I'll provide some code from the top of the file in question..
<?php
include("../include/session.php");
include("../include/admin_database.php");
Clearly this is the problem but I can't understand why!
Hope someone can help !
(question has been updated significantly since a lot of the answers below were submitted)
If you included the file two times, theen it gets re-declared. Use include_once() instead to prevent that easily.
If you are unsure where that class was originally declared, you can make use of the Reflection API to get the name of the file and the line of code:
$class = 'Database';
if(class_exists($class))
{
$oRefl = new ReflectionClass($class);
$message = sprintf('Class %s already defined in %s on line %s.', $class, $oRefl->getFileName, $oRefl->getStartLine);
throw new DomainException($message);
}
Place that before the line where you define the class Database to find out which file was originally defining the class.
Check if php already defines a file called Database.php.
Maybe you are using some framework or library which does.
You probably have included your database class more than once, a quick fix for this is to add something like this to the top of your class:
if(!class_exists('Database')){
class Database{
// so on
}
This ensures that your class is only defined once.
I'm getting this error:
Fatal error: Cannot redeclare class Customer
Then I added the following code:
if (!class_exists('Customer')) {
include('include/customer.class.php');
}
Why do I still get that error?
I have a file (file1.php) which has the Customer() class declared.
In file1.php I make an ajax call to file2.php
In file2.php I declare the Customer() class again.
In file2.php there is only 1 declaration of Customer() class.
Check if your server runs opcode cacher like APC - that's the cause of an error. I've runned into it recently.
Clearly due to the fact I issue:
if (!class_exists('Customer')) {
The class doesn't exist so the class itself is somehow duplicating itself.
I use this class in numerous other pages in the application without a problem.
I simply removed the whole thing:
if (!class_exists('Customer')) {
include('include/customer.class.php');
}
And it somehow worked which is preplexing!
If the class existed, the class file should never be included...
It doesn't exist therefore, the class is being included.
Once included, it says it's already included...
Very, very odd...
Well, it's working now... I guess i'll leave it be...
Use include_once(). If that still gives you an error, the problem is that you are declaring the class more than once in the file "include/customer.class.php"
http://php.net/include_once
The errors could be caused by a class defined multiple times, for example:
class Foo() {}
class Foo() {} // Fatal error
If you are not sure how many times your class will be included you can two things:
Use include_once() or require_once() in order to be sure that that file is required "once" only.
Write that code you provided every time you are including that file:
if (!class_exists('Customer')) {
include('include/customer.class.php');
}
I'd prefer the first though.
Your problem is the one described above. There must be a place where the class is declared multiple times. Without any code is hard to tell where.
Here's some references:
include_once()
require_once()
PHP: The Basics
I have a class file: class_xx.php. And then a function file: function_xxx.php
In my function_xxx.php:
require_once('class_xx.php')
... // after few next lines
$object = new class_xx1($arg1, $arg2);
But it gives me:
Fatal error: Class 'class_xx1' not found in "some_path" on line "1XX3"
[sorry I can't exposed the codes yet], any idea why I included the file > require_once with no error, but it gives me "Class not found error"??
Seemingly, the class_xx.php does not correctly declare the class_xx1 class. Review your code and watch for typos. Put some sort of debug line like echo "hello; in the required file if you want to be sure that it is being included correctly.
Chances are you misspelled the class declaration or something to that avail. You will what to double-check that your spell it the exact same way, with the same casing.
If you are developing on a secondary sever, you might have not transferred the completed class_xxx.php file over and just a blank file, in which case PHP would be including a blank file.
By the way, you forgot a semi-colon after the require_once