We Are Communication Architects

Building brand awareness through content creation and community engagement.

March 16th, 2011

Running WordPress from Command Line

When dealing with migrating data from other platforms into WordPress, I’ve run into issues with using a normal HTTP request to kick off the import due to amount of time the import takes. The best solution I’ve found is to have a script integrate into WordPress and kick it off from a command line instead of through an HTTP request, however, there are some tricks to getting this to work.

The first thing in setting up the command line script is adding the SheBang to the top of the PHP file. The SheBang points the shell to the executable that should be used to execute the script and while it isn’t required, it keeps you from constantly have to prepend script with the path to your PHP executable. For most systems, the path will be /usr/bin/php.

#!/usr/bin/php

The next step is to strap in WordPress’ bootstrap file, wp-load.php, now giving us:

#!/usr/bin/php
<?php
//require the WP bootstrap
require_once(dirname(__FILE__).'/wp-load.php');

But, just doing this, we’re going to run into a problem. WordPress is expecting certain $_SERVER variables to be set and if it doesn’t see them, it will try to redirect the request to the URL of where the site normally exists, causing your script to die before it gets to your code. So we need to setup the required $_SERVER variables.

#!/usr/bin/php
<?php

//setup global $_SERVER variables to keep WP from trying to redirect
$_SERVER = array(
  "HTTP_HOST" => "http://mysite.com",
  "SERVER_NAME" => "http://mysite.com",
  "REQUEST_URI" => "/",
  "REQUEST_METHOD" => "GET"
);

//require the WP bootstrap
require_once(dirname(__FILE__).'/wp-load.php');

//add your own code here

That’s it. You now have your WordPress instance bootstrapped into your script. The next thing would be to add any command line argument parsing to your script and adding the code to implement the needed actions.

#!/usr/bin/php
<?php

//setup global $_SERVER variables to keep WP from trying to redirect
$_SERVER = array(
  "HTTP_HOST" => "http://mysite.com",
  "SERVER_NAME" => "http://mysite.com",
  "REQUEST_URI" => "/",
  "REQUEST_METHOD" => "GET"
);

//require the WP bootstrap
require_once(dirname(__FILE__).'/wp-load.php');

class WP_Command_Line {

  public function __construct() {
    //nothing here
  }

  public function main($args = array()) {
    $defaults = array(
      'cmd' => 'get-last-postdate'
    );
    $args = wp_parse_args($args, $defaults);

    switch($args['cmd']) {
      case 'import':
        fwrite(STDOUT, get_lastpostdate());
      default:
        $this->prln("Invalid command specified.");
        break;
    }
  }
}


$args = parseArgs($argv);
$importer = new WP_Command_Line();
$importer->main($args);

function parseArgs($argv){
  array_shift($argv);
  $out = array();
  foreach ($argv as $arg){
    if (substr($arg,0,2) == '--'){
      $eqPos = strpos($arg,'=');
      if ($eqPos === false){
        $key = substr($arg,2);
        $out[$key] = isset($out[$key]) ? $out[$key] : true;
      } else {
        $key = substr($arg,2,$eqPos-2);
        $out[$key] = substr($arg,$eqPos+1);
      }
    } else if (substr($arg,0,1) == '-'){
      if (substr($arg,2,1) == '='){
        $key = substr($arg,1,1);
        $out[$key] = substr($arg,3);
      } else {
        $chars = str_split(substr($arg,1));
        foreach ($chars as $char){
          $key = $char;
          $out[$key] = isset($out[$key]) ? $out[$key] : true;
        }
      }
    } else {
      $out[] = $arg;
    }
  }
  return $out;
}

About the Author
Michael Pretty is an application developer for the Voce Connect Platforms team with a background in developing for PHP, mySQL, WordPress and a handful of other environments. Follow him on Twitter @prettyboymp

Filed in Development, WordPress

Add Your Comment3 Responses to “Running WordPress from Command Line”

Avinash on May 7th, 2011 at 1:43 pm

This is interesting. I’m trying to solve the same problem of migrating a few 100MB of data from different blogs hosted on another system into WordPress MU as different sites. Did you have to set username/password or $_COOKIE while inserting posts in the method described above?

Michael Pretty (prettyboymp) on May 13th, 2011 at 8:23 am

I wouldn’t bother setting the $_COOKIE params. I would just call set_current_user($user_id); so that any posts you save default to that user. Or just set the user_id field in the post data when you call the insert function.

Dave on December 19th, 2011 at 4:43 pm

Thank you for a succinct, easy-to-use script.