Patrick Maciel
Patrick Maciel

Reputation: 4944

PHP Fatal error: Cannot redeclare class AppModel

Env

Question

I'm using CakePHP with composer and everything is works.

But, when I try use cake bake and select option [V] View I get this error (see below):

$ app/Console/cake bake

Welcome to CakePHP v2.4.3 Console
---------------------------------------------------------------
App : app
Path: c:\workspace\site\src\app\
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q)
> v
---------------------------------------------------------------
Bake View
Path: c:\workspace\site\src\app\View\
---------------------------------------------------------------
Use Database Config: (default/test)
[default] >
Possible Controllers based on your current database:
---------------------------------------------------------------
 1. Groups
 2. Navigations
 3. PageImages
 4. Pages
 5. Sections
 6. Sliders
 7. Users
Enter a number from the list above,
type in the name of another controller, or 'q' to exit
[q] > 1
Would you like bake to build your views interactively?
Warning: Choosing no will overwrite Groups views if it exist. (y/n)
[n] > y
Would you like to create some CRUD views
(index, add, view, edit) for this controller?
NOTE: Before doing so, you'll need to create your controller
and model classes (including associated models). (y/n)
[y] > n
Would you like to create the views for admin routing? (y/n)
[n] > y
PHP Fatal error:  Cannot redeclare class AppModel in C:\workspace\site\Vendor\pear-pear.cakephp.org\CakePHP\Cake\Test\Case\Model\mode
ls.php on line 57

bootstrap.php

<?php
require ROOT . DS . 'Vendor/autoload.php';

// Remove and re-prepend CakePHP's autoloader as Composer thinks it is the
// most important.
// See: http://goo.gl/kKVJO7
spl_autoload_unregister(array('App', 'load'));
spl_autoload_register(array('App', 'load'), true, true);

How can I fix that?

Upvotes: 1

Views: 4245

Answers (3)

MarcoB
MarcoB

Reputation: 99

Even when I reregisterd the Cake Autoloader like Mark, I got Autoloading conflicts when using the auth Component, because of the Models Group, User and Product are defined a second time in Cake/Test/Case/Model/models.php

I resolved the issue by using a composer hook script and deleting the mapping within composers autoload_classmap

composer.json:

....
"scripts": {
        "post-autoload-dump": [
            "./composer_fix_autoload.sh"
        ]
    },
....

composer_fix_autoload.sh:

#!/bin/bash
mv vendors/composer/autoload_classmap.php vendors/composer/autoload_classmap.php.bak
sed '/CakePHP\/Cake\/Test\/Case\/Model\/models\.php/d' vendors/composer/autoload_classmap.php.ori > vendors/composer/autoload_classmap.php

Upvotes: 2

redd
redd

Reputation: 260

I've discovered, that it happens, when you have some association(s) in model for which you're baking views and the associated model class isn't baked yet.

Then somehow is used mapping from autoload_classmap.php:

'AppModel' => $vendorDir . '/pear-pear.cakephp.org/CakePHP/Cake/Test/test_app/Model/AppModel.php',

Unfortunately, I have too little knowledge to fix this bug.

Upvotes: 1

floriank
floriank

Reputation: 25698

The error message is clear: You're loading the AppModel two times somehow.

Cannot redeclare class AppModel in C:\workspace\site\Vendor\pearpear.cakephp.org\CakePHP\Cake\Test\Case\Model\models.php on line 57

Means that AppModel was loaded somewhere else already. My guess is that you have two installations of CakePHP. The path sounds like you have it installed via Pear and your text says you've used composer as well. So I guess the script is somehow loaded two times which causes the error when it tries to load it a second time for whatever reason. You'll have to figure out from where the class is loaded the first time, you can use reflections to figure that out.

$AppModel = new AppModel(/*...*/);
$Reflection = new ReflectionClass(get_class($AppModel ));
debug(dirname($Reflection->getFileName());

Further I guess the autoloader kicks in first and then, for a reason I don't know it also tries to load the core from the Pear installation.

Upvotes: 4

Related Questions