Drupal Command Line Script Template

Note: Drush is now a better option for running Drupal scripts. Please see this article for more information: Drupal Command Line Scripts with Drush.

There are development tasks better suited to running in a command-line script than in the Drupal web interface. The two most notable in my experience are code fragment testing, especially when exploring how an API works, and data import/export. Happily, this kind of scripting is possible with Drupal.

The PHP code shown below, created from examples seen in Planet Drupal posts, and later in the drush module, is serving me well as a command-line script template. It works in both Drupal 5 and 6.

Script Template

<?php
  $stdout
= fopen('php://stdout', 'w');
 
fwrite($stdout, "Script Template\n");

 
// Site specific variables
 
$username = "Dale";
 
$drupal_base_url = parse_url('http://www.example.com');

 
$_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
 
$_SERVER['PHP_SELF'] = $drupal_base_url['path'].'/index.php';
 
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
 
$_SERVER['REMOTE_ADDR'] = NULL;
 
$_SERVER['REQUEST_METHOD'] = NULL;

  require_once
'includes/bootstrap.inc';
 
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

  global
$user;
 
$user = user_load(array('name' => $username));

 
//
  //
  // Drupal code here
  //
  //
?>

Usage Notes

  • I strongly recommend using this only in a development environment and not on a production site.
  • Change the site specific variables $drupal_base_url and $username to values appropriate to your site.
  • The template code, as shown, must go in a file in the Drupal root directory. It can be moved as long as you set the working directory to the Drupal root directory (See drush module for examples).
  • If you want to output to your command line console before Drupal bootstrap, use fopen/fwrite, not echo or print. This avoids the warning: "Warning: Cannot modify header information - headers already sent". An example is provided in the script.

For those of you who might not be familiar with the Drupal Shell, or drush module, check it out before creating anything too fancy.

Running the Script

To run a script from the command line you need PHP configured to do so. Describing how to do so is outside the scope of this post. At the time of writing, the following Google search gave good results for "how to" references: Google Search: php command line. Some packages, such as XAMMP for Windows, set this up for you.

To quickly see if PHP is configured issue the command: php –v

You'll see the PHP version number if PHP is configured and an error if it isn't. It's also good to check which version of PHP is configured by default if your host or configuration supports multiple versions.

Running the script is as simple as: php my_script_name.php

For more information on PHP command line options, check out: PHP.net: Using PHP from the command line.

Acknowledgments

I'd like to acknowledge the authors of the following posts for their initial examples:

  1. Programatically Importing Data Into Drupal
  2. Benchmarking Drupal from the shell command line
AttachmentSize
script_template.php679 bytes

Comments

I'm a huge fan of these quick Drupal CLI scripts to do data migration or long-running jobs. Here's the one I've honed to my liking over time. I think it was originally based on one by Steve Rude (slantview). It has the added benefit of bailing out if being hit through the web server (only letting you hit it through the command line) and being able to handle a multisite setup:

#!/usr/bin/env php
<?php

// REMOTE_ADDR should always be set by the server, if it is we're not running on the CLI - exit
if(isset($_SERVER['REMOTE_ADDR'])){
print "Must be called from the command line.";
exit(1);
}

// this should be run with this script in the top-level of a drupal install, though the
// path given to the scipt may differ. Get the directory the script is in
// and chdir to it.
chdir(realpath(dirname(__file__)));

// This script must be called with one argument:
// the site name.
if ($argc != 2){
fwrite(STDERR, "Usage: ". $argv[0] ." SITENAME");
exit(1);
}

// Set up some server variables that are needed to
// bootstrap the correct drupal site.
$_SERVER['HTTP_HOST'] = $argv[1];
$_SERVER['PHP_SELF'] = basename(__file__);
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';

// Bootstrap drupal
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

// Optional: up time and memory limits for long running scripts
set_time_limit(10000);
ini_set('memory_limit', '1024M');

// Optional: perform tasks as UID=0
global $user;
$user = user_load(array('uid' => 0));

// CODE HERE

?>

Thanks for the script example!

I edited your example to add the closing "?>" so it would colorize.

A test to insure the script is only run from the command line is a great idea. I never bothered because my development environment is closed to the outside world (and like, I was being a little lazy :-) ), but actual code might prevent a potentially disastrous incident if the script was accidentally pushed production!

Although I didn't mention, the template in the post works fine on a multi-host configuration, as well. As with your script, it sets the $_SERVER['HTTP_HOST'] value.

Hi,
Thank you for the post. Maybe you can help me with my problem:
I have Drupal installed on a multi-site (following http://drupal.org/getting-started/6/install/multi-site).

drupal: root of drupal installation
drupal/sites/subdomain1.com
drupal/sites/subdomain2.com
...

Now I try to run a simple php script from the command line to retrieve the types of nodes contained in the drupal database.

The script:
<?php
//...
chdir('/path/to/drupal');
require_once('includes/bootstrap.inc');
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$results = db_query('select distinct type as type from node');
//...
?>

I returns the types contained in the top drupal database, the problem is that I want the types contained in a subdomain Drupal database (ex:subdomain1).

Can you help me with that?

I downloaded the script_template.php file changed it accordingly and when i run the file from the command line it shows the site offline message. The site is not Offline.
The site is running when i browse the site from the browser. Only when i run the php file from command line with the following lines the site offline message is displayed.

require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); // Including this line gives site offline message

can you please help me find the error.

I debugged and found the issue. Thought it would be useful to someone else if i posted here.

The issue was mysqli extension was not being loaded when i run the php script from the CLI. This is a problem with the hosting server and has been confirmed by the hosting provider. I found an alternative by using the mysql extension. This can be changed in the settings.php file for $db_url variable. It works now.