Source for file Abstract.php
Documentation is available at Abstract.php
* "THE BEER-WARE LICENSE" (Revision 42):
* "Sven Strittmatter" <ausserirdisch@sven-space.de> wrote this file.
* As long as you retain this notice you can do whatever you want with
* this stuff. If we meet some day, and you think this stuff is worth it,
* you can buy me a beer in return.
* @package Console_Application
* @copyright Copyright (c) 2009 Sven Strittmatter
* Console_Application_Interface.
* @see Console_Application_Interface
require_once('Console/Application/Interface.php');
* @see Console_Enviroment
require_once('Console/Enviroment.php');
require_once('Console/Exception.php');
* Console_Exception_MissingParameter.
* @see Console_Exception_MissingParameter
require_once('Console/Exception/MissingParameter.php');
* Template method class for CLI commands.
* @see HelloWorldApplication for an example implementation.
* @package Console_Application
* @uses Console_Application_Interface
* @uses Console_Exception
* @copyright Copyright (c) 2009 Sven Strittmatter
implements Console_Application_Interface {
* Name of the script. Appended with 'Application' its the
* Classname of your concrete implementation.
* Flag signals wheter the object is executed or not.
* Saves old php ini settings in for restoring.
* Flag signals whether the object is in verbose mode or not.
* On construction time a sapiCheck is done for CLI sapi.
* The php enviroment will be set and some default signal handlers are
* Throws a excpetion if the php enviroment ist not the command line.
* @param string $scriptname
* @param int $maxExecTime Optional;
* @param string $memoryLimit Optional;
* @throws RuntimeException if registerig signal handlers fails
* @throws RuntimeException if sapi check fails
public function __construct($scriptname, $maxExecTime = 60, $memoryLimit = '128M') {
$this->isExecuted = false;
$this->isVerbose = false;
$message = 'This is a command line script. ';
$message .= 'You have to call the shell script on ';
$message .= 'a terminal like bash.';
throw new RuntimeException($message);
* Restores the php ini settings stored in $iniSet.
private function resetPhpEnviroment() {
foreach ($this->iniSet as $name => $value) {
* Returns whether the application object is executed or not.
return $this->isExecuted;
* Returns whether the application object is verbose or not.
* This is set by the comandline option -v (in
* Console_Application_Abstract::findConsoleParameters()).
$this->isExecuted = true;
* This method wraps the php internal ini_set() that way,
* that it returns the old value.
protected function iniSet($name, $value) {
$this->iniSet[$name] = ini_get($name);
return $this->iniSet[$name];
* Template method. Try to run some method stubs in this order:
* <li>Console_Application_Abstract::findConsoleParameters()</li>
* <li>Console_Application_Abstract::setUp()</li>
* <li>Console_Application_Abstract::run()</li>
* <li>Console_Application_Abstract::tearDown()</li>
* If Console_Application_Abstract::findConsoleParameters() returns true the
* script execution aborts imediately.
* If in the templateed method structure any exception occures it is catched
* an the method Console_Application_Abstract::onError() is called. The
* exception object is passed to it.
* After that procedure two additional tear down methods will be called:
* <li>Console_Application_Abstract::setExecuted()</li>
* <li>Console_Application_Abstract::resetPhpEnviroment()</li>
$this->resetPhpEnviroment();
* This method listens by default to the console parameters -v and -h.
* By default -v enables the verbose mode
* (see Console_Application_Abstract::isVerbose()).
* By default -h calls Console_Application_Abstract::printHelpMessage() and
* To retrieve custom options overwite this mithed. Call the method an checks
* against false. Then check your options. If a required option is not
* set you should throw an Console_Exception_MissingParameter. This errors
* are handled in an default way to the console user
* (see Console_Exception_MissingParameter::onError()).
* Example implementation. Full example @see HelloWorldApplication
* protected function findConsoleParameters() {
* $options = getopt('n:s:');
* if (!parent::findConsoleParameters()) {
* if (isset($options['n']) && !empty($options['n'])) {
* $this->name = $options['n'];
* if (isset($options['s']) && !empty($options['s'])) {
* $this->sleep = (int) $options['s'];
* To brek the script if a user omitted a required console option you
* should implement it that way, because the onError() method handles
* Console_Exception_MissingParameter by default with nice user experience.
* protected function findConsoleParameters() {
* $options = getopt('n:');
* if (!parent::findConsoleParameters()) {
* if (isset($options['n']) && !empty($options['n'])) {
* $this->name = $options['n'];
* throw new Console_Exception_MissingParameter('n');
* For more details about getting options by getopt()
* @link http://de.php.net/manual/en/function.getopt.php
* @return bool Must return false to abort script execution!
if (isset ($options['h'])) {
if (isset ($options['v'])) {
* Template method stub. Overwrite this method to hook the set up phase of
* your script. This method is called after
* Console_Application_Abstract::findConsoleParameters(),
* unless it returns false. And before Console_Application_Abstract::run().
* By default this method does nothing!
* Return values are not evaluated.
protected function setUp() {
* You need to implement this method. Put your stuff to do here.
* Return values are not evaluated.
abstract protected function run();
* Template method stub. Overwrite this method to hook the tear down phase
* of your script. This method is called after
* Console_Application_Abstract::run(), unless any exception was throwed.
* And before Console_Application_Abstract::setExecuted().
* By default this method does nothing!
* Return values are not evaluated.
* This method is called if in the three followed methods a exception was
* <li>Console_Application_Abstract::findConsoleParameters()</li>
* <li>Console_Application_Abstract::setUp()</li>
* <li>Console_Application_Abstract::run()</li>
* <li>Console_Application_Abstract::tearDown()</li>
* Exceptions of the (sub)type Console_Exception are handled by defaukt
* <dt>Console_Exception_MissingParameter</dt>
* <dd>The exeption message and the return string of getUsage() will
* <dt>Console_Exception</dt>
* <dd>The excpetion message will be echoed.</dd>
* @todo php catchabel errors abfangen: error_handler setzen.
protected function onError($errorData) {
$this->echoMsg($errorData->getMessage());
$this->echoMsg($errorData->getMessage());
$this->echoMsg('Fatal error occured! Script aborts...');
* Returns a help message. Its called by default object behavier, if you
* suply -h to the script. By default it returns a line break formatted
* This is a sample console application. It prints some hello world statements.
* Usage: {$scriptName} [-h] [-v]
* {$scriptName} -v : Sets the script in verbose mode.
* {$scriptName} -h : prints this help message.
* For bug reporting or issues contact: foo@bar.de
* You can customize the help message your wy. See an example implementation
* (@see HelloWorldApplication)
* protected function getHelpMessage($author = '...', $email = '...') {
* $message = "This is a sample console application. It prints some ";
* $message .= "hello world statements." . PHP_EOL . PHP_EOL;
* $message .= $this->getUsage() . PHP_EOL;
* $message .= "\t{$this->scriptname} -n : You can specify a name to ";
* $message .= §be hellowed" . PHP_EOL;
* $message .= "\t{$this->scriptname} -s : You can specify the seconds ";
* $message .= §to sleep between hello and name." . PHP_EOL;
* $message .= parent::getHelpMessage($author, $email);
* throw new Console_Exception($message);
$message .= "\t{$this->scriptname} -v : Sets the script in verbose mode. ";
$message .= "\t{ $this->scriptname} -h : prints this help message. ";
$message .= PHP_EOL . PHP_EOL;
$message .= "Written by $author." . PHP_EOL;
$message .= "For bug reporting or issues contact: $email" . PHP_EOL;
* Returns a usage string like:
* Usage: {$scriptName} {$options} [-h] [-v]
* By example implementation (@see HelloWorldApplication) its:
* Usage: helloworld.sh [-n] [-s] [-h] [-v]
public function getUsage($options = '') {
( ('' !== $options) ? $options . ' ' : '' ) .
* Echoes a string appended with PHP_EOL.
* If you call it without parameter it makes newlines ;-)
public function echoMsg($msg = '') {
if (defined('TESTS_CONSOLE_APPLICATION')) {
* Registers some signal handlers:
* <dt>Console_Application_Abstract::signalTerm()</dt>
* <dt>Console_Application_Abstract::signalInt()</dt>
* <dt>Console_Application_Abstract::signalHangUp()</dt>
* IS called on construction time. Overwrite this methid
* @throws RuntimeException If pcntl_signal() doesnt exists
* @link http://de.php.net/manual/en/pcntl.setup.php
* @throws RuntimeException If pcntl_signal() failes.
protected function registerSignalHandlers() {
$messgae = 'The function pcntl_signal() is not available! ';
$messgae .= 'Its neccessary to compile PHP with the option --enable-pcntl.';
throw new RuntimeException($messgae);
$message = 'Cant register signal handler for ';
if (!pcntl_signal(SIGTERM, array(&$this, 'signalTerm'))) {
throw new RuntimeException($message . 'SIGTERM!');
if (!pcntl_signal(SIGINT, array(&$this, 'signalInt'))) {
throw new RuntimeException($message . ' SIGINT!');
if (!pcntl_signal(SIGHUP, array(&$this, 'signalHangUp'))) {
throw new RuntimeException($message . ' SIGHUP!');
protected function isPcntlEnabled() {
return function_exists('pcntl_signal');
* Signal handler registered by Console_Application_Abstract::registerSignalHandlers().
* By default it echoes a message and calls Console_Application_Abstract::tearDown().
* Overwrite this method to react on SIGTERM.
* @access public neccesary for pcntl_signal()
public function signalTerm($signal) {
$this->echoMsg('Script aborted by SIGTERM!');
* Signal handler registered by Console_Application_Abstract::registerSignalHandlers().
* By default it echoes a message and calls Console_Application_Abstract::tearDown().
* Overwrite this method to react on SIGINT.
* @access public neccesary for pcntl_signal()
public function signalInt($signal) {
$this->echoMsg('Script aborted by SIGINT!');
* Signal handler registered by Console_Application_Abstract::registerSignalHandlers().
* By default it echoes a message and calls Console_Application_Abstract::tearDown().
* Overwrite this method to react on SIGHUP.
* @access public neccesary for pcntl_signal()
public function signalHangUp($signal) {
$this->echoMsg('Script aborted by SIGHUP!');
* Sets the the php enviroment by ini settings to a proper default.
* <li>max_execution_time</li>
* <li>html_errors = false</li>
* <li>implicit_flush = true</li>
* The old values are stored in Console_Application_Abstract::iniSet array.
* So they can be restored by Console_Application_Abstract::resetPhpEnviroment().
* If you wanne make some custom ini settings in your script overwrite
* protected function setPhpEnviroment($memoryLimit, $maxExecutionTime) {
* parent::setPhpEnviroment($memoryLimit, $maxExecutionTime);
* $this->iniSet('YOUR_SETTED_INI_NAME', 'YOUR_CUSTOM_VALUE');
* If you do it this wy its guranted that the enviroment is resetted
* properly after execution.
* Do not use ini_set() directly!
* @param string $memoryLimit
* @param int $maxExecutionTime
protected function setPhpEnviroment($memoryLimit, $maxExecutionTime) {
$this->iniSet('memory_limit', $memoryLimit);
$this->iniSet('max_execution_time', $maxExecutionTime);
$this->iniSet('html_errors', false);
$this->iniSet('implicit_flush', true);
|