Zend 1.10 / Doctrine 2、XMLマッピングでスキーマを処理できません
-
30-09-2019 - |
質問
現在、ORM Doctrine 2をZend Frameworkと統合しようとしています。 Xmldriverを使用しようとしています。
スキーマを生成しようとするまで、すべてが正常に機能します。実際、エンティティはよく作成されています。
したがって、これがブートストラップファイルです:
<?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();
これがXMLマッピングファイルです 製品 例:
<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 Directoryで生成されます。
しかし、スキーマを生成しようとすると、次の例外/エラーが得られます。
./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
ありがとうございます。
解決
このコードにいくつかの問題があります:
$classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models/entities');
$classLoader->setNamespaceSeparator('_');
マッピングファイルでは、バックスラッシュセパレーターを使用してエンティティクラス名を宣言しています。エンティティでレガシークラス名を使用しているようには見えず、セパレーターを変更する必要はありません。
マッピングファイルでは、エンティティの完全に適格な名前空間があることを宣言しています
models\entities\Product
, しかし、あなたは名前空間を次のように登録しているだけですEntities
構成ファイルで。次のように登録する必要がありますModels
教義が名前空間解像度を適切に行うために。また、名前空間でケースを混ぜません(する必要がありますModels\Entities\Product)
.最後に、名前空間を登録すると、Doctrineは、提供するベースパスからクラスを探し始め、名前空間を追加します。だから登録
Entities
あなたが持っているように、教義は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' );