我目前正在尝试将ORM Doctrine 2与Zend Framework集成。 我尝试使用XMLDriver。
在我尝试生成架构之前,一切正常。实际上,这些实体创造得很好。
所以,这是bootstrap文件:
<?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_
* @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;
}
}
最后这里是doctrine.php文件:
<?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();
这是 Product 示例的XML Mapping文件:
<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>
正如我所说,当我尝试创建实体时,一切正常:
./doctrine orm:generate-entities ../application
Processing entity "models\entities\Product"
Entity classes generated to "/var/www/mysite/application"
Product.php在Application \ models \ entities \目录中生成。
但是当我尝试生成模式时,我得到以下异常/错误:
./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
谢谢你的帮助。
答案 0 :(得分:3)
我发现此代码存在一些问题:
$classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models/entities');
$classLoader->setNamespaceSeparator('_');
在映射文件中,您使用反斜杠分隔符声明实体类名称。您似乎没有在实体中使用旧版类名,也无需更改分隔符。
在映射文件中,您声明实体的完全限定名称空间为models\entities\Product
,但是,您只是在配置文件中将名称空间注册为Entities
。您需要将其注册为Models
以便Doctrine正确执行命名空间解析。我也不会在命名空间中混合大小写(应该是Models\Entities\Product)
。
最后,在注册名称空间时,Doctrine将开始从您提供的基本路径中查找类并附加名称空间。因此,请注册Entities
,Doctrine将在Entities
下的application/models/entities/Entities/
命名空间中查找任何内容。
如果您希望模型类的命名空间为Models\Entities\Product
,请使用此命名空间加载命名空间(并将models
文件夹重命名为Models
):
$classLoader = new \Doctrine\Common\ClassLoader('Models', APPLICATION_PATH);
通常,我使用应用程序级命名空间来放置所有内容。所以我的模型将是命名空间App\Entities\Product
,我的自动加载看起来像:
$classLoader = new \Doctrine\Common\ClassLoader('App', APPLICATION_PATH . '/models' );