Memcache deleteMulti not working - php

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);

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.

New MongoId() solution during migration from PHP 5.5 to in PHP 7

In PHP7 new MongoId() is not working and solution to get mongo id in php7 using below function var_dump(new MongoDB\BSON\ObjectId()), but I am using this in multiple files almost more than 200 files so I don't want manually edit all these files.
So can anybody tell me is there any trick like using __autolaod(),spl_autoload_register() function so we can add some code and that will will automatically called for new MongoId() function and return the mongoID without an error.
I just need a smart solution without editing multiple files.

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');
...
?>

Renaming a Mongo Collection in PHP

PHP's Mongo driver lacks a renameCommand function. There is reference to do this through the admin database. But it seems more recent versions of the Mongo driver don't let you just "use" the admin database if do don't have login privileges on that database. So this method no longer works. I've also read this doesn't work in sharded environments although this isn't a concern for me currently.
The other suggestion people seem to have is to iterate through the "from" collection and insert into the "to" collection. With the proper WriteConcern (fire and forget) this could be fairly fast. But it still means pulling down each record over the network into the PHP process and then uploading it back over the network back into the database.
I ideally want a way to do it all server-side. Sort of like an INSERT INTO ... SELECT ... in SQL. This way it is fast, network efficient and a low load on PHP.
I have just tested this, it works as designed ( http://docs.mongodb.org/manual/reference/command/renameCollection/ ):
$mongo->admin->command(array('renameCollection'=>'ns.user','to'=>'ns.e'));
That is how you rename an unsharded collection. One problem with MR is that it will change the shape of the output from the original collection. As such it is not very good at copying a collection. You would be better off copying it manually if your collection is sharded.
As an added note I upgraded to 1.4.2 (which for some reason comes out from the pecl channel into phpinfo() as 1.4.3dev :S) and it still works.
Updates:
Removed my old map/reduce method since I found out (and Sammaye pointed out) that this changes the structure
Made my exec version secondary since I found out how to do it with renameCollection.
I believe I have found a solution. It appears some versions of the PHP driver will auth against the admin database even though it doesn't need to. But there is a workaround where the authSource connection param is used to change this behavior so it doesn't auth against the admin database but instead the database of your choice. So now my renameCollection function is just a wrapper around the renameCollection command again.
The key is to add authSource when connecting. In the below code $_ENV['MONGO_URI'] holds my connection string and default_database_name() returns the name of the database I want to auth against.
$class = 'MongoClient';
if( !class_exists($class) ) $class = 'Mongo';
$db_server = new $class($_ENV['MONGO_URI'].'?authSource='.default_database_name());
Here is my older version that used eval which should also work although some environments don't allow you to eval (MongoLab gives you a crippled setup unless you have a dedicated system). But if you are running in a sharded environment this seems like a reasonable solution.
function renameCollection($old_name, $new_name) {
db()->$new_name->drop();
$copy = "function() {db.$old_name.find().forEach(function(d) {db.$new_name.insert(d)})}";
db()->execute($copy);
db()->$old_name->drop();
}
you can use this. "dropTarget" flag is true then delete exist database.
$mongo = new MongoClient('_MONGODB_HOST_URL_');
$query = array("renameCollection" => "Database.OldName", "to" => "Database.NewName", "dropTarget" => "true");
$mongo->admin->command($query);

Zend Doctrine2 memcache vs PHP Memcache class

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.

Categories