Sometimes you may only need to run a few PHP commands after bootstrapping Drupal. For example, to view the value of a server variable, to programmatically submit a form, and to print the output of a very complex database query that needs some placeholders. Normally, to achieve this, you would copy index.php
to a temporary file, remove the line that invokes the controller and type in your own code. Drush helps you do this more easily and securely through the commands php-eval
and php-script
.
php-eval
accepts some PHP code between quotes and executes it. If it can bootstrap a Drupal site, it will do it first, allowing us to interact with it. Here are a couple of examples:
$ cd /home/juampy/projects
$ drush php-eval "print ini_get('error_reporting'),"
30719
$ drush php-eval "print variable_get('site_name', 'not found'),"
PHP Fatal error: Call to undefined function variable_get() in /usr/share/drush/commands/core/core.drush.inc(637) : eval()'d code on line 1
Drush command terminated abnormally due to an unrecoverable error. [error]
$ cd drupal
$ ls sites/
all default example.sites.php
$ drush php-eval "print variable_get('site_name', 'not found')," Festival
We firstly placed ourselves at a non Drupal directory and executed a couple of commands. The first one worked fine as it was pure PHP code, but the second one failed because Drush could not bootstrap a Drupal site. After that, we changed directory to the root of a Drupal site with its settings.php
located at sites/default
(which is discoverable by Drush) and executed the same command. Drush found the settings.php
, bootstrapped Drupal, and extracted the value from the variables table.
Evaluating PHP code from the command line is fine with two or three PHP statements. More than that becomes harder to read and tricky to escape if it has double or single quotes. This is when we'd rather use a PHP script that the php-script
command will execute for us after bootstrapping Drupal.
If you need to keep these scripts, it is a good practice to keep them outside your Drupal installation or in a safe directory within Drupal so they won't get executed in a production environment by mistake.
Let's suppose that we want to delete all comments submitted by a particular user. We could create the following script to accomplish it. Create a file named delete-comments.php
outside of your Drupal root path with the following contents:
<?php // Custom PHP script to delete comments made by a user id $uid = 100; // The user id (uid). Set this to the uid of the user whose comments you want to delete. $result = db_select('comment', 'c') ->fields('c', array('cid')) ->condition('uid', $uid) ->execute(); $counter = 0; foreach ($result as $record) { comment_delete($record['cid']); $counter++; } print "Deleted " . $counter . " comments.";
Now we will change directory to the Drupal root where we want to execute and run it:
$ cd /home/juampy/projects/drupal
$ drush php-script --script-path=../ delete-comments
Deleted 72 comments.
We specified the path where the script is (one level higher for this example) and the filename without the extension (our filename is delete-comments.php
, so we only have to type delete-comments)
. Then Drush bootstrapped Drupal and executed our script.
You can list all scripts available from your current path and by paths provided by the --script-path
option by not typing a script filename, like in the following example:
$ drush php-script script-path=../
/usr/share/drush/commands/core/scratch.php
/home/juampy/projects/drupal/authorize.php
/home/juampy/projects/drupal/install.php
/home/juampy/projects/drupal/xmlrpc.php
/home/juampy/projects/drupal/update.php
/home/juampy/projects/drupal/cron.php
/home/juampy/projects/drupal/index.php
../delete-comments.php
18.221.222.47