0

I intend to run a script using ZendFramework library from CLI. My script is as following:

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

It can run in a browser, but failed in a command prompt. How can I let the script run from CLI?

Thanks!

asdk77
  • 143
  • 1
  • 2
  • 12
  • possible duplicate of [How to load Zend classes when running php script by command lines](http://stackoverflow.com/questions/20204457/how-to-load-zend-classes-when-running-php-script-by-command-lines) – Phil Nov 26 '13 at 22:17
  • Yes, I posted both the questions. Thanks to all the answers! I have fixed the problem now. – asdk77 Nov 27 '13 at 16:00

1 Answers1

1

this post has some the info you are looking for: Running a Zend Framework action from command line


Below you will find complete functional code that I wrote and use for cron jobs within my apps...

Need to do the following:

  1. pull required files in you cli file
  2. initialize the application and bootstrap resources. Here you can capture cli params and setup request object so it is dispatched properly.
  3. set controller directory
  4. run the application

Here is documentation on Zend_Console_Getopt that will help you understand how to work with cli params.

code for cli.php

<?php

// Define path to application directory
defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV') || define('APPLICATION_ENV', 'development');

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/libraries'),
    get_include_path(),
)));

//  initialize application
require_once 'My/Application/Cron.php';
$application = new My_Application_Cron(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
$application->bootstrap();

//
Zend_Controller_Front::getInstance()->setControllerDirectory(APPLICATION_PATH . '/../scripts/controllers');

//
$application->run();

My_Application_Cron class code:

<?php

//  because we are extending core application file we have to explicitly require it
//  the autoloading occurs in the bootstrap which is part of this class
require_once 'Zend/Application.php';

class My_Application_Cron extends Zend_Application
{

    protected $_cliRequest = null;

    protected function _bootstrapCliRequest()
    {
        $this->_isCliBootstapped = true;

        try {
            $opts = array(
                'help|h' => 'Displays usage information.',
                'action|a=s' => 'Action to perform in format of module.controller.action',
                'params|p=p' => 'URL-encoded parameter list',
                //'verbose|v' => 'Verbose messages will be dumped to the default output.',
            );
            $opts = new Zend_Console_Getopt($opts);
            $opts->setOption('ignoreCase', true)
                ->parse();

        } catch (Zend_Console_Getopt_Exception $e) {
            exit($e->getMessage() . "\n\n" . $e->getUsageMessage());
        }

        //  See if help needed
        if (isset($opts->h)) {
            $prog = $_SERVER['argv'][0];
            $msg = PHP_EOL
                . $opts->getUsageMessage()
                . PHP_EOL . PHP_EOL
                . 'Examples:' . PHP_EOL
                . "php $prog -a index.index'" . PHP_EOL
                . "php $prog -a index.index -p 'fname=John&lname=Smith'" . PHP_EOL
                . "php $prog -a index.index -p 'name=John+Smith'" . PHP_EOL
                . "php $prog -a index.index -p 'name=John%20Smith'" . PHP_EOL
                . PHP_EOL;

            echo $msg;
            exit;
        }

        //  See if controller/action are set
        if (isset($opts->a)) {
            //  Prepare necessary variables
            $params = array();
            $reqRoute = array_reverse(explode('.', $opts->a));
            @list($action, $controller, $module) = $reqRoute;

            //  check if request parameters were sent
            if ($opts->p) {
                parse_str($opts->p, $params);
            }

            //
            $this->_cliRequest = new Zend_Controller_Request_Simple($action, $controller, $module);
            $this->_cliRequest->setParams($params);
        }
    }

    public function bootstrap($resource = null)
    {
        $this->_bootstrapCliRequest();

        return parent::bootstrap($resource);
    }

    public function run()
    {
        //  make sure bootstrapCliRequest was executed prior to running the application
        if (!($this->_cliRequest instanceof Zend_Controller_Request_Simple)) {
            throw new Exception('application required "bootstrapCliRequest"');
        }

        //  set front controller to support CLI
        $this->getBootstrap()->getResource('frontcontroller')
            ->setRequest($this->_cliRequest)
            ->setResponse(new Zend_Controller_Response_Cli())
            ->setRouter(new Custom_Controller_Router_Cli())
            ->throwExceptions(true);

        //  run the application
        parent::run();
    }

}

To lean how to run the cli scipt simply type command below in terminal:

#> php /path/to/cli.php -h

Hopefully this will help you and others!

Community
  • 1
  • 1
Alex
  • 6,441
  • 2
  • 25
  • 26
  • Thank you! But I am not very clear about your codes. Do you mean to run the script with cli.php or include 'cli.php' in the script that I want to run? If I just want to use 'Zend_Rest_Client' class, how can I load the class for the script? For example, my script to be run named "zf_test.php". – asdk77 Nov 26 '13 at 22:00
  • =) in order to include any zend class you need to make sure autoloading is setup or include child and all parent classes! Look into Zend_Autoloader http://framework.zend.com/manual/1.12/en/learning.autoloading.usage.html. then simply instantiate the object you need in your script. My code in post will allow you to write script logic in model/controller structure and execute in command line. – Alex Nov 27 '13 at 04:57
  • Yes, when I included the library path and made "autoloader", it can work now. Thank you! – asdk77 Nov 27 '13 at 15:58