I would like to use Doctrine (v2.4) in my ZendFramework (v1.11) application, which I am starting from scratch. There are some articles describing such integration, but they seem quite complicated and a little out of date. Is there any fairly simple way to connect ZF1 and Doctrine2?
I've implemented this as an application resource (extending \Zend_Application_Resource_ResourceAbstract)
The code is quite long so below is a top level check list of the requirements.
Create a doctrine entity manager configuration instance (Doctrine\ORM\Configuration).
$config = new Doctrine\ORM\Configuration();
Populate the configuration with the required data (metadata driver, cache config etc). Doctrine's documentation is a good reference here to what would be required (http://docs.doctrine-project.org/en/latest/reference/configuration.html)
Example here uses the Annotation driver:
$driver = new Driver\AnnotationDriver(
new Annotations\CachedReader(new Annotations\AnnotationReader(), new Cache\ArrayCache()),
$entityDirs
);
$config->setMetadataDriverImpl($driver);
Lastly pass this new config instance to the static entity manager EntityManager::create
E.G. ($options here is the database connection info as exampled in the above link)
$entityManager = EntityManager::create($options['database'], $config);
Take a look at my full source, at the very least it will give you a head start:
https://github.com/alex-patterson-webdev/Multiverse/blob/master/lib/Multiverse/Application/Resource/Entitymanager.php
Related
I'm trying to understand the difference between regular Memcache and Doctrine's MemcacheCache.
In my bootstrap I instantiate Memcache like this:
$memcache = new Memcache;
$memcache->connect('localhost', 11211);
\Zend_Registry::set("pdc_memcache_core", $memcache);
I then have the following code for instantiating Doctrine - this is not the full code as I'm just looking at the cachine:
$doctrineConfig = new \Doctrine\ORM\Configuration();
$memcacheCore = \Zend_Registry::get("pdc_memcache_core");
$cache = new \Doctrine\Common\Cache\MemcacheCache;
$cache->setMemcache($memcacheCore);
$cache->setNamespace("PDC_");
\Zend_Registry::set("pdc_memcache", $cache);
$doctrineConfig->setMetadataCacheImpl($cache);
$doctrineConfig->setQueryCacheImpl($cache);
I then access the cache like this:
if (\Zend_Registry::get("pdc_memcache")->contains($cacheKey)) {
...
}
I'm not trying to store Doctrine entities in Memcache - I'm just storing strings and serialised arrays.
Now... is this the correct way to use Memcache with Doctrine? I can see that you use setMemcache to assign the Memcache instance to Doctrine's MemcacheCache... but would I use MemcacheCache for my own stuff? Or should I use the Memcache instance directly?
Would really appreciate some thoughts on this, as I'm confused by how this is supposed to link together.
It is perfectly ok to use the Memcache Cache of Doctrine Common, thats also the correct way and you also have some abstraction that allows you to consume any Doctrine\Common\Cache\Cache instance. I'm not quite sure you would need that anyway, as you're working with Zend Framework, and you probably could use the CacheManager or it's associated CacheManager resource, which both would give you the advantage to make your caching mechanism configurable.
I can say I am familiar with doctrine 1.2.X and I've used hibernate quite a while but i was surprised to be facing difficulties when trying out the Doctrine 2.
I find it confusing especially when it assumes one is using pear which am not.
basically i have simple basic questions on configurations
here is my project folder structure
doctrine2
bootstrap_doctrine.php
bootstrap.php
cli_config.php
--/entities
--/lib
----/Doctrine
------/Common
------/DBAL
------/ORM
------/Symfony
--/tools
-----doctrine
-----doctrine.bat
-----doctrine.php
my bootstrap_doctrine.php according to the manual looks like this
use Doctrine\ORM\Tools\Setup;
require_once 'lib/Doctrine/ORM/Tools/Setup.php';
$lib = __DIR__. "/lib/Doctrine";
$isDevMode = true;
\Doctrine\ORM\Tools\Setup::registerAutoloadDirectory($lib);
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/entities"), true);
$conn = array(
"driver"=>"pdo_mysql",
"path"=>"127.0.0.1",
"dbname"=>"doctrinetest",
"user"=>"root",
"password"=>"rootpass"
);
$entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);
my boostrap.php looks the same as the one on the doc page.now comes the cli_config.When it comes to that tools doc suggests things that where already done in the bootstrap_doctrine but then there are other things that succeeded in confusing me.things such as the creation of the $config object and $cli application object.
So here are my questions.
question 1 what exactly is the use of cli_config?
question 2 to run command line functions should i use /tools/doctrine or /cli_config ?
question 3 what are proxies for (same as proxies in spring/hibernate )?
question 4 what represents hibernate DAO/Services in doctrine 2? repositories?
thanks for reading this and helping out.
I'm converting an old PHP project to the Symfony2 framework. Some of the pages are now handled by my Symfony2 front controller (index.php), but many pages have not yet been converted.
The problem is that, within Symfony, all of my Doctrine entity annotations must begin with the ORM\ prefix, but outside of Symfony, that prefix does not appear to be enabled, and so I get the following error:
Class MyProject\MyBundle\Entity\MyClass is not a valid entity or mapped super class.
I've tried to duplicate whatever magic Symfony does to set this up, including following these instructions [doctrine-project.org], and actually including app/autoload.php entirely into my legacy bootstrap process. But nothing works.
Does anyone know how I can manually replicate whatever it is that Symfony does to enable the ORM\ prefix for my Doctrine annotations?
I got the answer from the Symfony2 Google group. The problem is that the Doctrine configuration shown in the documentation uses SimpleAnnotationReader behind the scenes, but you need regular AnnotationReader to use the ORM\ namespace prefix. I got it to work by replacing this:
$config = new Doctrine\ORM\Configuration();
$driver = $config->newDefaultAnnotationDriver('/path/to/my/entities');
with this:
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
// ...
$config = new Doctrine\ORM\Configuration();
$reader = new AnnotationReader();
$driver = new AnnotationDriver($reader, '/path/to/my/entities');
I ended up with:
Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($paths, $devMode, null, null, false);`
The 3rd and 4th null arguments are default. The 5th false argument tells it to make a standard AnnotationReader rather than a basic one.
I'm using Doctrine 2.5.6.
Explanation
I found I couldn't get Ian's solution working without calling Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration before making my own config. I was getting this error:
'[Semantical Error] The annotation "#Doctrine\ORM\Mapping\Entity" in class My\Class does not exist, or could not be auto-loaded.'
I was really confused so I took a look at the source code.
It turns out createAnnotationMetadataConfiguration calls Doctrine\ORM\Configuration::newDefaultAnnotationDriver rather than creating the annotation driver directly. This calls AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php'); which seems to be critical. After that, newDefaultAnnotationDriver just creates a new AnnotationDriver().
I would like to integrate Doctrine 2 ORM into WordPress for use in the plugins I'm developing. There is currently a plugin that offers Doctrine 1.2.3 ORM support in WordPress, but not v2.
The biggest problem I'm having is that I don't understand how Doctrine 2 ORM interacts with my code; specifically, what their configuration code provides me with and where I should go from here:
// 3.1.1
require dirname( __FILE__ ) . '/lib/Doctrine/ORM/Tools/Setup.php';
$lib = dirname( __FILE__ ) . '/lib';
Doctrine\ORM\Tools\Setup::registerAutoloadDirectory($lib);
// 3.1.2
use Doctrine\ORM\EntityManager,
Doctrine\ORM\Configuration;
if($applicationMode == "development") {
$cache = new \Doctrine\Common\Cache\ArrayCache;
} else {
$cache = new \Doctrine\Common\Cache\ApcCache;
}
$config = new Configuration;
$config->setMetadataCacheImpl($cache);
$driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
$config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies');
$config->setProxyNamespace('MyProject\Proxies');
if ($applicationMode == "development") {
$config->setAutoGenerateProxyClasses(true);
} else {
$config->setAutoGenerateProxyClasses(false);
}
$connectionOptions = array(
'driver' => 'pdo_sqlite',
'path' => 'database.sqlite'
);
$em = EntityManager::create($connectionOptions, $config);
I had continued reading through sections of the documentation up to section 8 and have some understanding. My questions are:
Is this configuration enough to allow me to work with Doctrine 2 ORM in my plugins?
Are there any other key steps I'm missing before working with Doctrine 2 ORM? The WordPress plugin seems to automatically generate all of the appropriate classes from the database. I read the documentation a few times, but I feel like I'm missing some big step... or maybe Doctrine 2 ORM is just that much different?
Is the EntityManager some global variable that I can use throughout my entities?
I assume I have to link everything together, #Entity in a file is not enough for Doctrine to know where the entity is. Is there somewhere in the documentation that defines this?
If anyone can provide a quick rundown of how it all works together: configuration, entities, etc. Or provide any clear cut tutorials that may already be out there, I would really appreciate it.
IMHO you shouldn't use Doctrine2 with WP
Doctrine 2 is more appropriate solution for site with huge business logic and I believe you don't use WP for this purposes
Doctrine 2 has huge code base (~11MB) which add overhead for classloading and processing of requests
Doctrine 2 use a lot of memory with default hydration mode (object)
Building custom sql is much harder with Doctrine.
Can someone explain what a compilerpass is?
CompilerPass implementations are some kind of listeners that are executed after dependency injection container is built from configuration files and before it is saved as plain PHP in cache. They are used to build some structures that requires access to definitions from outer resources or need some programming that is not available in XML/YAML configuration. You can consider them as "final filters" that can modify entire DIC.
Let's consider a TwigBundle and its TwigEnvironmentPass. What it does is quite simple:
Fetch a reference to twig service (defined as <service id="twig" class="..." ...>)
Find all services that has been tagged with twig.extension tag. To do that you have work on complete DIC (built from XML configuration files) as those services might be defined in any bundle.
Build a custom code for service creation method.
As a final result the following code will be generated:
protected function getTwigService()
{
$this->services['twig'] = $instance = new \Twig_Environment($this->get('twig.loader'), ...);
// THIS HAS BEEN ADDED THANKS TO THE TwigEnvironmentPass:
$instance->addExtension(new \Symfony\Bundle\SecurityBundle\Twig\Extension\SecurityExtension($this->get('security.context')));
$instance->addExtension(new \Symfony\Bundle\TwigBundle\Extension\TransExtension($this->get('translator')));
$instance->addExtension(new \Symfony\Bundle\TwigBundle\Extension\TemplatingExtension($this));
$instance->addExtension(new \Symfony\Bundle\TwigBundle\Extension\FormExtension(array(0 => 'TwigBundle::form.html.twig', 1 => 'SiteBundle::widgets.html.twig')));
$instance->addExtension(new \MyProject\SiteBundle\Twig\Extension\MyVeryOwnExtensionToTwig($this));
return $instance;
}