Zend Doctrine2 memcache vs PHP Memcache class - php

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.

Related

Symfony cache dont work with class/object

I use some php library, and generate element of class
$elnew = new LibClass();
I want to save this variable to cache.
If I make like this
$elem = $cache->getItem($ig_name);
if (!$elem->isHit()) {
$elem->set($elnew);
$cache->save($ig);
}
$elem->isHit() is always false. I checked how cache works with string - all is ok.
Also I'm not able to serialyze/unserialyze this object because it says
Serialization of 'Closure' is not allowed
and no way to modify LibClass
How can I save $elnew to cache? Any variants for with symfony components? Or maybe other libs can help me?
Serialization of 'Closure' is not allowed
You can use the PHP SuperClosure library to get rid of this.
Also you can try other memory storages like Redis or Memcache to cache your objects. See this resolved stackoverflow question.

Working with the latest PHP / MongoDB version

After much of a struggle I managed to install MongoDB as a service and WAMP. Then on start I got a fatal error saying these would not work:
$m = new Mongo(...);
$m = new MongoClient(...);
In some previous questions on SO people mentioned using a new class called MongoDB/Driver/Manager. I also came across something called MongoDB/Client.
As a beginner to MongoDB I now stand rather confused about how to use/connect to a DB and collection.
I guess I will use:
$m = new MongoDB/Driver/Manager(...);
However,
$db = $m->$dbname; // Seems to cause -> Notice: Undefined Property
$collection = $db->shows; // dito
So all in all what are the difference between MongoDB/Driver/Manager and MongoDB/Client ? And with these new classes how would I correctly connect to a DB or Collection as shown in the previous snippet ? I can't seem to find many examples explaining how to use these new classes, or an up to date correct way of using the new classes for basic functionality.
Thanks,
I think I understand what I am confusing.
Using the MongoDB/Driver/Manager class and others, are part of the basic tools available with the PHP MongoDB Driver. I am guessing it is not recommended using them unless you know what you are doing, or you want something relatively customized.
A more recommendable alternative is to install "mongodb/mongodb-^1.x.x" with a PHP installer such as Composer, which will give you a MongoDB Library. This will give you classes such as the MongoDB/Client class.
Once the library has been installed you can connect like so:
<?php
require 'vendor/autoload.php';
$client = new MongoDB/Client('mongodb://localhost:27017');
// Add URI of MongoDB here
$mydb = $client->mydb; // Add the new DB name or existing DB name here
$collection = $mydb->createCollection('userCollection');
...
?>

Memcache deleteMulti not working

I have memcache 2.2.7 installed (using PECL on localhost) and currently using the PHP Memcache(d) class. I am trying to delete multiple keys in one function call using one of the documented methods:
simplified code:
$memcache = new \Memcache;
$memcache->deleteMulti($key_list);
However, I get an error:
"Call to undefined method Memcache::deleteMulti()"
The argument $key_list is an array of keynames as required. Does anyone know the reason for this? Has this method been recalled? Is it possible I am not actually using the Memcached class, but Memcache instead? How can I tell? If it is not possible to use this method, is there an alternative that will allow me to delete up to a few hundred keys at once, and do it FAST?
The Memcache ext does not have deleteMulti method, this is the reason of this error.
You can use Memcached:
$memcache = new \Memcached;
$memcache->deleteMulti($key_list);

Integrate Zend Framework 1 and Doctrine 2

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

Different behaviour with and without Symfony's response system

I'd like to be able to manage WebDAV directories (and even reimplement the way files are read and written) in Symfony. To do so I found SabreDAV, which is itself a framework with all the basic classes required.
My problem is, while it's quite easy to get a WebDAV server running using SabreDAV alone, it doesn't work that well when I use Symfony.
Without Symfony, it boils down to:
$server = new DAV\Server($rootDirectory);
$server->exec();
And I can use cadaver to access my directory.
More here: http://code.google.com/p/sabredav/wiki/GettingStarted
I tried to do the same in my controller with Symfony, using:
return new Response($server->exec());
but for some reason cadaver doesn't have access to the folder.
I guess I'm missing something about the way responses work in Symfony, but what? SabreDAV uses its own system of http requests and responses, but if (as I presume) Symfony doesn't mess with superglobal variables such as $_SERVER, this shouldn't be an issue.
About requests and responses in Symfony: http://symfony.com/doc/current/book/http_fundamentals.html#requests-and-responses-in-symfony
Here's what I did; it's a bit slow and there must be a better way, but I'll make do with that for the moment:
Controller.php :
$path=(__DIR__.'/../../../../web/public/');
$path=realpath($path);
$publicDir= new \MyClasses\FS\MyDirectory($path);
$server = new \Sabre\DAV\Server($publicDir);
$server->setBaseUri('/Symfony/web/app_dev.php/');
{
$SyRequest = Request::createFromGlobals();
$_server=$SyRequest->server->all();
$_post=$SyRequest->request->all();
}
{
$SaRequest=new \MyClasses\HTTP\Request($_server,$_post);
$resourceStream=false;
$SaRequest->setBody($SyRequest->getContent($resourceStream),$resourceStream);
}
{
$server->httpRequest=$SaRequest;
$SaResponse=new \MyClasses\HTTP\Response();
$server->httpResponse=$SaResponse;
$server->exec();
}
{
$content=ob_get_clean();
}
{
$SyResponse=new Response($content,http_response_code(),headers_list());
}
return $SyResponse;
$server->exec();
Doesn't really return anything. It attempts to set headers itself, and stream the output to php://output (indeed, with the built-in request/response system).
If you want to embed SabreDAV into symfony, the most proper way to solve this is to subclass both Sabre\HTTP\Request and Sabre\HTTP\Response, and set these in the server (setting the ->httpRequest and ->httpResponse properties) before calling ->exec.
Your overridden request/response objects should then map to symfony's equivalents.
I don't know enough about symfony to tell you if they map cleanly and easily though, and I imagine it will in practice be simpler to try to work around symfony's system (although from an architectural standpoint, it will not be the most proper).

Categories