I often need to run routines (that might take a long time) from the command line.  For example, a nightly import of thousands of records.  I did this all the time in Drupal 7.  Here's how you need to set it up in Backdrop:

First: Create a "/routines" directory, and add this .htaccess file to it (so no one can run your routine from the web):

# Turn off all options we don't need.
Options -Indexes -ExecCGI -Includes

# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  # Override the handler again if we're run later in the evaluation list.
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>

# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php5.c>
  php_flag engine off
</IfModule>
<IfModule mod_php7.c>
  php_flag engine off
</IfModule>
<IfModule mod_php.c>
  php_flag engine off
</IfModule>

# Deny all requests from Apache 2.4+.
<IfModule mod_authz_core.c>
  Require all denied
</IfModule>

# Deny all requests from Apache 2.0-2.2.
<IfModule !mod_authz_core.c>
  Deny from all
</IfModule>

 

Next, create a my_routine.php file (named whatever) in that directory which is your routine:

 

<?php

// Begin by defining the location of your backdrop root directory.
// Here we assume this file is located in backdropdir/routines/file.php.  If not, simply set
// this variable to exactly what the directory path is.  Ex:  /var/www/html/backdrop
define('BACKDROP_ROOT', dirname(dirname(__FILE__)));

// Change the directory to the Backdrop root.
chdir(BACKDROP_ROOT);

include_once BACKDROP_ROOT . '/core/includes/bootstrap.inc';
backdrop_bootstrap(BACKDROP_BOOTSTRAP_FULL);


// Double-check to make sure we are running this script from the command line and not the web
if (php_sapi_name() !== 'cli' && php_sapi_name() !== 'cgi-fcgi') {
  die("Sorry, this script is only meant to be run from the command line.");
}


/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// At this point, you should have full access to all the backdrop functions as well as all
// module functions.  Ex: node_load(), db_query(), my_module_xyz(), etc.


$start = time();
print "\n -- Starting routine -- \n";


// TODO: DO CODE HERE.



// All done-- print how long it took us to the command line.
print "\n -- Finished routine in " . (time() - $start) . " seconds. \n\n";

 

From crontab or on the CLI, run your routine with:

php /path/to/backdrop/routines/my_routine.php

Easy peasy.

Hope this helps someone!

 

Accepted answer

I just wanted to post a "how-to" on this subject ;)

Comments

I just wanted to post a "how-to" on this subject ;)

Bee's great.  But if you don't want to install bee, or can't, or you already have a bunch of scripts you're used to using in D7, then the method I posted is quick and easy and all you really need are 4 lines of code at the top of your php file.

I mean, for this use case, the difference is:

bee scr /path/to/script.php

vs

php /path/to/script.php

Why go through the extra overhead if I don't need to?

The .htaccess file and check to ensure you're on the CLI would be the same in either case (if your routine file is in the web root, which in my use case I want it to be so it's all in the same git repo).