I'm writing some plugins that do background batch processing, i.e. operations that take longer than 30 seconds. I'm creating objects with the necessary job parameters set like this (this is a hugely simplified example):

class MyPlugin_Create_Terms {
    public $job_id;
    public $terms;
    public $taxonomy;
    public $created = 0;
    public function init( $terms, $taxonommy ) {
         $this->job_id = uniqid();
         $this->terms = $terms;
         $this->taxonomy = $taxonomy;
         return $this->job_id;
    public function do_job( $object_storage ) {
         foreach( $this->terms as $term ) {
             wp_insert_term( $term, $this->taxonomy );
             $object_storage->save_object( $this->job_id, $this );

$create_terms = new MyPlugin_Create_Terms();
$job_id = $create_terms->init( $_POST['user_input_terms'], $_POST['user_input_taxonomy'] );
$object_storage = new MyPlugin_Object_Storage();
$object_storage->save_object( $job_id, $create_terms );

And in another process:

$object_storage = new MyPlugin_Object_Storage();
$create_terms = $object_storage->load_object( $job_id );
$create_terms->do_job( $object_storage );

While anywhere else:

$object_storage = new MyPlugin_Object_Storage();
$create_terms = $object_storage->load_object( $job_id );
echo "We have created {$create_terms->created} terms.";

Now the problem is implementing the Object_Storage. I have figured out the following options for storing objects:

  1. Transients. They apparently won't do, since they have no guaranteed life-time (with caching, the transients might never be written to the database, I've learned).

  2. Existing DB tables. Serialized PHP objects should not be saved to MySQL text fields, since they might contain NULL bytes (( I had a spectacular WSOD failure when serializing an object with a protected property to the usermeta table) :

    Note that this is a binary string which may include null bytes, and needs to be stored and handled as such. For example, serialize() output should generally be stored in a BLOB field in a database, rather than a CHAR or TEXT field. - PHP Manual: serialize()

  3. Creating a custom table with BLOB type fields for serializing any object or alternatively, storing the object data without serializing. Feels like overkill. What are the best practices?

  4. Using the filesystem. Various factors like locking, atomic and non-atomic processes and file permissions complicate this. Specifically, since there will be two processes accessing the object concurrently, there is the problem with race conditions when they need to look at the same object.

  5. Using _SESSION? Probably not good for two concurrent processes.

Any thoughts would be appreciated!

  • Multi-process tasks are not common to WordPress (sans wp-cron, which is not quite elaborate solution). My opinion would be to look for prior art in general PHP development, before deciding on implementation details in WP environment.
    – Rarst
    Commented Feb 12, 2014 at 18:39
  • 1
    One the one hand, there're Iterators in PHP SPL that implement Serializable - you can do the same for custom classes. When I read through your "problem", then I ask myself what you're really (in detail) trying to do. Currently it's just "background process" and some buzzwords that aren't really related: protected properties & serializing object, filesystem components, Session, extra tables. Please file an edit and show us (in code as well) what you're really trying to do. Leaving it open...
    – kaiser
    Commented Feb 14, 2014 at 10:29
  • @kaiser: Edited.
    – P_Enrique
    Commented Feb 14, 2014 at 18:54

2 Answers 2


Store the object temporarily in the database, but implement __sleep() and __wakeup() to avoid side effects.

Alternatively, implement the Serializable interface and prepare the data in its methods. There is no need to store NULL values.

  • I think this is the way to go. I had implemented a __sleep() function, but it let slip a protected property, which gets serialized as with the key \NULL*\NULLpropertyname. Private properties get serialized with the key \NULLclassname\NULLpropertyname. So you have to take care to serialize only public properties.
    – P_Enrique
    Commented Feb 12, 2014 at 20:21

Long term, you should consider that if you have a process which is going to regularly exceed the max execution time, then running it from inside an HTTP request and polling isn't a great idea. Consider using the real cron system instead. Command line PHP processes don't have a max execution time, normally, and can run until completion.

Short term, if you want to store it safely in a text field, like in a custom post type or meta or something, serialize it, then base64_encode the string. This will solve your problem with the null bytes. Just decode it and unserialize it when you need to retrieve it again.

  • This is about processes launched by the user, not scheduled maintenance jobs. I know of three ways to run a process on the background avoiding a browser timeout, out of which the command line process seems to be the most prone to break: users might now have exec rights, the php interpreter might be in an unknown location, and you'll have to fake _SERVER vars to get WordPress to load. The base64_encoding is an interesting idea.
    – P_Enrique
    Commented Feb 12, 2014 at 20:58
  • Also I want to mention that on my laptop, deleting 40 attachments is enough to cause a timeout. I'm trying to design something that will work on blogs that might have thousands of posts, so timeouts are a big issue.
    – P_Enrique
    Commented Feb 12, 2014 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.