Cannot redefine class on 'require_once'
-
24-10-2019 - |
Question
UPDATE:
I've abandoned CodeIgniter, and the desire to build a web interface around my database application from PHP, as there was no way of getting rid of this bug...
The Exception
I get this exception:
Fatal error: require_once(): Cannot redeclare class doctrine\orm\abstractquery in Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php on line 190
Call Stack:
0.0007 330016 1. {main}() Q:\Digest\index.php:0
0.0058 330800 2. require_once('Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php') Q:\Digest\index.php:163
0.2207 935856 3. call_user_func_array() Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php:297
0.2207 935904 4. Crud->index() Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php:0
0.2574 1065064 5. Crud->__getEntities() Q:\Digest\Application\controllers\crud.php:19
0.2649 1121824 6. Doctrine\ORM\AbstractQuery->getResult() Q:\Digest\Application\controllers\crud.php:49
0.2649 1121976 7. Doctrine\ORM\AbstractQuery->execute() Q:\Digest\lib\Doctrine\ORM\AbstractQuery.php:366
0.2651 1121976 8. Doctrine\ORM\Query->_doExecute() Q:\Digest\lib\Doctrine\ORM\AbstractQuery.php:528
0.2651 1121976 9. Doctrine\ORM\Query->_parse() Q:\Digest\lib\Doctrine\ORM\Query.php:223
0.2848 1185896 10. Doctrine\ORM\Query\Parser->parse() Q:\Digest\lib\Doctrine\ORM\Query.php:203
0.3089 1238704 11. Doctrine\ORM\Query\SqlWalker->getExecutor() Q:\Digest\lib\Doctrine\ORM\Query\Parser.php:311
0.3090 1239104 12. Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
0.3107 1241104 13. require_once('Q:\Digest\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php') Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
0.3108 1241440 14. Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
I am using Doctrine 2.0, with the Symfony UniversalClassLoader
, as can be seen above, to implement a data-analysis script. To view the results, I have set up a CodeIgniter project.
Here's what has me baffled with this exception: I have eliminated almost all reasonably causes, and found nothing. Tell me if I did something wrong in the elemination rounds here.
If anyone has any clue whatsoever about what might be going wrong here, please help. Should you think there is any information I've left out, also, please tell me.
Thank you.
Eliminating duplicate declarations
It tells me I cannot redefine a class. I have grepped all my files, and this class is defined only in its specific file "Doctrine/ORM/AbstractQuery.php".
Note that initially the error was reported at the call to require
at line 190 of the Symfony UniversalClassLoader.php, and I have changed this to require_once
to make sure the file isn't loaded twice.
Eliminating the case-sensitive filesystem
Because of the note I found here, I think it's I should share that I'm running PHP 5.3.5 on Windows 7. This should mean the bug/feature described below is of no influence.
This behaviour changed in PHP 5, so for example with Windows the path is normalized first so that C:\PROGRA~1\A.php is realized the same as C:\Program Files\a.php and the file is included just once.
Eliminating require
duplication
I've now gone so far as to replace every single call in every library (and my own code) to the function require
to one to require_once
, and the error persists unchanged. This means that I can now safely say that no call to require
is responsible. My question remains: what is?
Debugger Output
Running a debugger brings me absolutely nothing:
...
0.4658 1274904 -> Doctrine\ORM\Query\SqlWalker->getExecutor() Q:\Digest\lib\Doctrine\ORM\Query\Parser.php:311
0.4660 1275304 -> Logger::autoload() Q:\Digest\lib\Log4PHP\Logger.php:0
0.4662 1275304 -> Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
0.4663 1275384 -> strripos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:183
0.4665 1275400 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:185
0.4666 1275488 -> strpos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:187
0.4667 1275520 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:188
0.4668 1275672 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4669 1275696 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4671 1275656 -> file_exists() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
0.4700 1277304 -> require_once(Q:\Digest\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php) Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:192
0.4702 1277640 -> Logger::autoload() Q:\Digest\lib\Log4PHP\Logger.php:0
0.4703 1277640 -> Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
0.4704 1277720 -> strripos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:183
0.4706 1277736 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:185
0.4707 1278280 -> strpos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:187
0.4708 1278312 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:188
0.4709 1278464 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4711 1278488 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4712 1278448 -> file_exists() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
0.5259 zu
TRACE END [2011-03-28 11:28:00]
Some additional inspection tells me that the file it's loading while it crashes is lib\Doctrine\ORM\Query\Exec\AbstractSqlExecutor.php
, or the AbstractSqlExecutor
class... thus, something completely unrelated.
Solution
The other possibilities I can think of (after skimming the answers proposed so far) are:
Maybe there is a symlink somewhere in your source tree? (I've found that require_once() isn't smart enough to know that you're importing the same file if the path looks different).
Maybe there's a cycle somewhere in your inclusion dependencies? (if A includes B which includes C which includes A, I've found that require_once() isn't smart enough to break the cycle).
OTHER TIPS
Please check if your server has APC installed. If so try to turn it off, upgrade or set apc.include_once_override setting to 0.
Too bad you gave up. The simple way to fix it would be to put:
if (!class_exists('ClassName')) {
}
around the file. This doesn't fix the bug, just makes the symptom go away. Codeigniter is unfortunately not too smart about PHP5 object instantiation, and may be loading your code twice.
Are you using __autoload() anywhere? Thats the only thing I can think of, unless you actually have the same class defined in two DIFFERENT files.
If you have explored all of the obvious solutions, then every time I have run into this problem, it's been a caching problem, typically with APC.
If it is an apc caching problem, to fix it, add the following to your top level file at the top of the file:
apc_clear_cache();
If the problem disappears, then you know that that was the issue. In particular on shared hosting environments, if files are changing, I've found APC almost unusable, so I always add that to a top level file I can call.
PS: I've even run into situations where it seems like APC has cached the wrong file, so that it crashes when I include a file that clearly never had the class it's complaining about.
If you are including UniveralClassLoader
in multiple ways, such as:
- through
require_once
- use
Symfony\Component\ClassLoader\UniversalClassLoader;
then the fatal error might be caused by what the compiler considers the redeclaration of the class. Remove require_once
line if it exists and just use the second option.
you may have the same class defined in two files. require_once() won't help in that case
root
+ a.php
+ c/
+c.php
+ b.php
_ a.php _
require_once 'c/b.php'; -> will work
require_once 'c/c.php'; -> will work
_ c/b.php _
require_once 'c.php'; -> will work too 'c/c.php'!='c.php' :(