PHP shell scripts for Magento

PHP Shell scripts for magento

There are times when it’s necessary to access Magento system from outside Magento. A way to do this is using PHP shell script that bootstraps Magento. An average PHP developer would just go to Magento root directory to create Magento bootstrap file with it’s own code at the bottom. As you’ve probably guessed, there are two ways to bootstrap Magento, regular way and Magento way. In this article I’ll provide an overview of Magento way of creating PHP shell scripts.

For starters, here’s regular way of bootstrapping Magento (the one that regular Magento’s index.php is using):

require_once 'app/Mage.php;
Mage::app();
// Our own code goes here

There’s nothing wrong with this approach, but there are some downsides when compared to Magento way.

The Magento way

Now let’s move on to the second way of creating PHP shell scripts intended to interact with Magento code. If you go to path_to_magento_root/shell you will find some PHP shell scripts created in “Magento way”. For example you have indexer.php you can use to reindex by selected indexers, or compiler.php to control Magento compiler feature status. If you take a look inside these PHP shell scripts, you’ll see that they include path_to_magento_root/shell/abstract.php file containing Mage_Shell_Abstract class and that they contain classes that extend Mage_Shell_Abstract class.

Some of you might wonder how’s this better than just simply requireing Mage.php, especially if you take a look at Mage_Shell_Abstract’s constructor that does pretty much the same thing?

One of upsides of using Magento way is that Mage_Shell_Abstract class provides you with tools for parsing command line arguments with ease. Seccond thing, the Mage_Shell_Abstract class constructor will call Mage_Shell_Abstract::__applyPhpVariables() function to parse .htaccess file and apply php settings to shell script.

Even though it’s pretty much obvious how to proceed from here, I’ll paste skeleton class for a Magento PHP shell script here:

<?php
require_once 'abstract.php';
class Inchoo_Shell_Myscript extends Mage_Shell_Abstract
{
    protected $_argname = array();
    public function __construct() {
        parent::__construct();
        // Time limit to infinity
        set_time_limit(0);
        // Get command line argument named "argname"
        // Accepts multiple values (comma separated)
        if($this->getArg('argname')) {
            $this->_argname = array_merge(
                $this->_argname,
                array_map(
                    'trim',
                    explode(',', $this->getArg('argname'))
                )
            );
        }
    }
    // Shell script point of entry
    public function run() {
    }
    // Usage instructions
    public function usageHelp()
    {
        return <<<USAGE
Usage:  php -f scriptname.php -- [options]
  --argname <argvalue>       Argument description
  help                   This help
USAGE;
    }
}
// Instantiate
$shell = new Inchoo_Shell_Myscript();
// Initiate script
$shell->run();

Precache PHP shell script

I’ll also point you towards PHP shell script created as an exercise, after similar functionality was required for one of our projects. This is a PHP script intended to populate cache for Magento site. The idea was to visit all Magento URLs using Zend_Http_Client (both product canonical and category based URLs as well as all category URLs). This script allows you to select which stores and categories should be processed using command line arguments. Here’s download link:

Inchoo Precache Download

And here’s link to Inchoo_Precache Magento shell script’s GitHub repository.and link to Inchoo_Precache Magento shell script’s GitHub repository:

Inchoo Precache GitHub Repository

And here are the usage instructions available using php -f precache.php -- help command from terminal inside shell directory of your Magento root after adding precache.php to your Magento installation:

Usage:  php -f precache.php -- [options]
  --stores <names>       Process only these stores (comma-separated)
  --categories <names>   Process only these categories (comma-separated)
  help                   This help

Magento way is the way to go, don’t you agree? Happy coding!

6
Top

Care to rate this post?

Author

Marko Martinovic

Backend Developer

If you ask him – “Marko, how do you relax in your free time?”, he would most probably say: – “I write some code.” Let’s cut to the chase, he is one passionate programmer who currently lives his dream by working for Inchoo.

Other posts from this author

Discussion 6 Comments

Add Comment
  1. Thanks – this is quite handy. To share some experiences. We have had such a script and realized that some pages have many rewrites. And as a result caching took hours for 99% of page urls that hardly generate any traffic.

    The solution was to capture the sitemap.xml (location can be grabbed dynamic per store from code) and this was parsed and every page grabbed.

    Let me know what you tink

  2. And one more comment. Super thanks btw!!

    How do I know if it has been or is running? I dont see anything at the command line.

    Major thanks Marko

  3. Markus

    Nice Tutorial and working! It would be great, if the precache script could be run in background without using the webserver. Running the scripts without the httpd gives me error:
    Unable to Connect to tcp://mydomain.example:80. Error #111: Connection refused…

    The following snippet for example (reading order details) uses only Magento API and it can be started without runnning httpd:

        public function run()
        {
            $model   = Mage::getModel('sales/order_api');
            $results = $model->info(100000001); // order inc-id
            print_r($results);
        }
    
  4. @Overhemden

    Hi. The script should actually display verbose information on command line while running. If this isn’t the case then something is wrong.

    Regards

  5. @Markus

    Hello! What this script does is visits pages to generate cache and this isn’t possible without web server running.

    Regards,
    Marko

  6. Joe

    I am getting the following error while trying to run this script

    PHP Fatal error: Cannot break/continue 1 level in /var/www/html/shell/precache.php on line 150

    protected function _precacheProcessStore($store)
        {
            $storeName = $store-&gt;getName();
            if(!empty($this-&gt;_precacheStores) &amp;&amp;
                    !in_array($storeName, $this-&gt;_precacheStores)) {
                continue;
            }
            printf('Processing &quot;%s&quot; store'.&quot;\n&quot;, $storeName);
            $this-&gt;_precacheSCount++;
            Mage::app()-&gt;setCurrentStore($store-&gt;getId());
            $rootCategory = Mage::getModel('catalog/category')
                -&gt;load($store-&gt;getRootCategoryId());
            $this-&gt;_precacheProcessCategory($rootCategory, $store);
            echo &quot;\n&quot;;
        }

    I have looked up the error and it has been pointed out that you cannot break out of an IF statement.

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top