Zend 1.10 / Doctrine 2, can't process the schema with XML mapping
I am currently trying to integrate the ORM Doctrine 2 with Zend Framework. I try to use the XMLDriver.
Everything works fine until I try to generate the schema. Indeed, the entities are well created.
So, here is the bootstrap file :
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
/**
* generate registry
* @return Zend_Registry
*/
protected function _initRegistry() {
$registry = Zend_Registry::getInstance();
return $registry;
}
/**
* Register namespace App_
*开发者_JS百科 @return Zend_Application_Module_Autoloader
*/
protected function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => dirname(__FILE__),
));
new Doctrine\Common\ClassLoader('Application', APPLICATION_PATH );
return $autoloader;
}
/**
* Initialize auto loader of Doctrine
*
* @return Doctrine_Manager
*/
function _initDoctrine() {
// setup Zend & Doctrine Autoloaders
require_once "Doctrine/Common/ClassLoader.php";
$zendAutoloader = Zend_Loader_Autoloader::getInstance();
// $autoloader = array(new \Doctrine\Common\ClassLoader(), 'loadClass');
$autoloader = array(new \Doctrine\Common\ClassLoader('Symfony'), 'loadClass');
$zendAutoloader->pushAutoloader($autoloader, 'Symfony\\');
$autoloader = array(new \Doctrine\Common\ClassLoader('Doctrine'), 'loadClass');
$zendAutoloader->pushAutoloader($autoloader, 'Doctrine\\');
$autoloader = array(new \Doctrine\Common\ClassLoader('DoctrineExtensions'), 'loadClass');
$zendAutoloader->pushAutoloader($autoloader, 'DoctrineExtensions\\');
$autoloader = array(new \Doctrine\Common\ClassLoader('Application\\Models', realpath(__DIR__ . '/..')), 'loadClass');
$zendAutoloader->pushAutoloader($autoloader, 'Application\\Models\\');
$autoloader = array(new \Doctrine\Common\ClassLoader('Application\\Proxies', realpath(__DIR__ . '/..')), 'loadClass');
$zendAutoloader->pushAutoloader($autoloader, 'Application\\Proxies');
$autoloader = array(new \Doctrine\Common\ClassLoader('DoctrineExtensions'), 'loadClass');
$zendAutoloader->pushAutoloader($autoloader, 'DoctrineExtensions\\');
// setup configuration as seen from the sandbox application
// TODO: read configuration from application.ini
$config = new \Doctrine\ORM\Configuration;
$cache = new \Doctrine\Common\Cache\ArrayCache;
$config->setMetadataCacheImpl($cache);
//$driverImpl = $config->newDefaultAnnotationDriver(realpath(__DIR__ . '/models'));
$driverImpl = new \Doctrine\ORM\Mapping\Driver\XmlDriver(array(APPLICATION_PATH . '/models/entities/mapping'));
$driverImpl->setFileExtension('.xml');
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
$config->setProxyDir(APPLICATION_PATH . '/models/proxies');
$config->setProxyNamespace('Application\\Proxies');
$config->setAutoGenerateProxyClasses(true);
$doctrineConfig = $this->getOption('doctrine');
$connectionOptions = array(
'driver' => $doctrineConfig['connection']['driver'],
'host' => $doctrineConfig['connection']['host'],
'port' => $doctrineConfig['connection']['port'],
'user' => $doctrineConfig['connection']['user'],
'password' => $doctrineConfig['connection']['password'],
'dbname' => $doctrineConfig['connection']['dbname']
);
// setup entity manager
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
Zend_Registry::set("entitymanager", $em);
return $em;
}
}
Finally here is the doctrine.php file :
<?php
ob_start();
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
define('APPLICATION_ENV', 'development');
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
)));
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPLICATION_PATH . '/../library');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', APPLICATION_PATH . '/../library/Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models/entities');
$classLoader->setNamespaceSeparator('_');
$classLoader->register();
// Create application, bootstrap
/** Zend_Application */
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();
$em = $application->getBootstrap()->getResource('doctrine');
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
$helperSet = ($helperSet) ? : new \Symfony\Component\Console\Helper\HelperSet();
$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface', Doctrine\ORM\Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
$cli->addCommands(array(
// DBAL Commands
new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
// ORM Commands
new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
));
$cli->run();
here is the XML Mapping file for the Product example:
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="models\entities\Product" table="products">
<id name="id" type="integer" column="product_id">
<generator strategy="AUTO" />
</id>
<field name="name" column="product_name" type="string" />
</entity>
</doctrine-mapping>
As I said, when I try to create the entities everything works fine :
./doctrine orm:generate-entities ../application
Processing entity "models\entities\Product"
Entity classes generated to "/var/www/mysite/application"
And the Product.php is generated in the Application\models\entities\ directory.
But when I try to generate the schema I get the following exceptions/errors :
./doctrine orm:schema-tool:create
PHP Warning: class_parents(): Class models\entities\Product does not exist and could not be loaded in /var/www/mysite/library/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 224
PHP Warning: array_reverse() expects parameter 1 to be array, boolean given in /var/www/mysite/library/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 224
PHP Warning: Invalid argument supplied for foreach() in /var/www/mysite/library/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 224
[ReflectionException]
Class models\entities\Product does not exist
orm:schema-tool:create [--dump-sql] [-h|--help] [-q|--quiet] [-v|--verbose] [-V|--version] [-c|--color] [-n|--no-interaction] command
Warning: class_parents(): Class models\entities\Product does not exist and could not be loaded in /var/www/mysite/library/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 224
Warning: array_reverse() expects parameter 1 to be array, boolean given in /var/www/mysite/library/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 224
Warning: Invalid argument supplied for foreach() in /var/www/mysite/library/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 224
Thank you for you help.
I see a few problems with this code:
$classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models/entities');
$classLoader->setNamespaceSeparator('_');
In your mapping files, you are declaring your entity class names using backslash separator. You do not appear to be using legacy class names in your entities, and have no need to change the separator.
In your mapping files, you are declaring the fully qualified namespace of your entity to be
models\entities\Product
, however, you are only registering the namespace asEntities
in your config file. You need to register it asModels
for Doctrine to properly do namespace resolution. I would also not mix case in the namespace (should beModels\Entities\Product)
.Finally, when registering namespaces, Doctrine will start looking for classes from the base path you provide and append the namespace. So registering
Entities
as you have, Doctrine will look for anything in theEntities
namespace underapplication/models/entities/Entities/
.
If you want your namespace for model classes to be Models\Entities\Product
, use this to load the namespace (and rename your models
folder to Models
):
$classLoader = new \Doctrine\Common\ClassLoader('Models', APPLICATION_PATH);
Typically, I use an application-level namespace to put everything under. So my models would be namespaced App\Entities\Product
and my autoload looks like:
$classLoader = new \Doctrine\Common\ClassLoader('App', APPLICATION_PATH . '/models' );
精彩评论