J'aimerais lancer une action Zend Framework pour générer des fichiers en ligne de commande. Est-ce possible et combien de changements devrais-je apporter à mon projet Web existant qui utilise ZF?
Merci!
J'aimerais lancer une action Zend Framework pour générer des fichiers en ligne de commande. Est-ce possible et combien de changements devrais-je apporter à mon projet Web existant qui utilise ZF?
Merci!
Mise à JOUR
Alors que la solution n ° 1 est ok, parfois, vous voulez quelque chose de plus élaboré. Surtout si vous attendez d'avoir plus que juste un script CLI. Si vous me le permettez, je voudrais proposer une autre solution.
Tout d'abord, avez dans votre Bootstrap.php
protected function _initRouter ()
{
if (PHP_SAPI == 'cli')
{
$this->bootstrap ('frontcontroller');
$front = $this->getResource('frontcontroller');
$front->setRouter (new Application_Router_Cli ());
$front->setRequest (new Zend_Controller_Request_Simple ());
}
}
Cette méthode a pour effet de priver le dispatching de contrôle de routeur par défaut en faveur de notre propre routeur Application_Router_Cli.
D'ailleurs, si vous avez défini vos propres itinéraires en _initRoutes pour votre interface web, vous souhaiterez probablement de les neutraliser lorsqu'en mode ligne de commande.
protected function _initRoutes ()
{
$router = Zend_Controller_Front::getInstance ()->getRouter ();
if ($router instanceof Zend_Controller_Router_Rewrite)
{
// put your web-interface routes here, so they do not interfere
}
}
Classe Application_Router_Cli (je suppose que vous avez de chargement automatique activé pour l'Application de préfixe) peut ressembler à:
class Application_Router_Cli extends Zend_Controller_Router_Abstract
{
public function route (Zend_Controller_Request_Abstract $dispatcher)
{
$getopt = new Zend_Console_Getopt (array ());
$arguments = $getopt->getRemainingArgs ();
if ($arguments)
{
$command = array_shift ($arguments);
if (! preg_match ('~\W~', $command))
{
$dispatcher->setControllerName ($command);
$dispatcher->setActionName ('cli');
unset ($_SERVER ['argv'] [1]);
return $dispatcher;
}
echo "Invalid command.\n", exit;
}
echo "No command given.\n", exit;
}
public function assemble ($userParams, $name = null, $reset = false, $encode = true)
{
echo "Not implemented\n", exit;
}
}
Maintenant, vous pouvez simplement exécuter votre application par l'exécution de
php index.php backup
Dans ce cas cliAction méthode dans BackupController contrôleur sera appelée.
class BackupController extends Zend_Controller_Action
{
function cliAction ()
{
print "I'm here.\n";
}
}
Vous pouvez même aller de l'avant et modifier Application_Router_Cli classe afin de ne pas "cli" des mesures sont prises à chaque fois, mais quelque chose que l'utilisateur a choisi, par le biais d'un paramètre supplémentaire.
Et une dernière chose. Définir un gestionnaire d'erreur pour l'interface de ligne de commande de sorte que vous ne serez pas voir tout le code html sur votre écran
Dans Bootstrap.php
protected function _initError ()
{
$error = $frontcontroller->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
$error->setErrorHandlerController ('index');
if (PHP_SAPI == 'cli')
{
$error->setErrorHandlerController ('error');
$error->setErrorHandlerAction ('cli');
}
}
Dans ErrorController.php
function cliAction ()
{
$this->_helper->viewRenderer->setNoRender (true);
foreach ($this->_getParam ('error_handler') as $error)
{
if ($error instanceof Exception)
{
print $error->getMessage () . "\n";
}
}
}
Il est vraiment beaucoup plus facile que vous pourriez penser. Le bootstrap/composants de l'application et de vos configs peut être réutilisé avec la CLI de scripts, tout en évitant le MVC pile et le poids inutile qui est invoquée dans une requête HTTP. C'est un avantage de ne pas à l'aide de wget.
Commencez votre script comme votre votre public index.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',
(getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
: 'production'));
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/config.php'
);
//only load resources we need for script, in this case db and mail
$application->getBootstrap()->bootstrap(array('db', 'mail'));
Vous pouvez ensuite procéder à l'utilisation de ZF ressources comme vous le feriez dans une application MVC:
$db = $application->getBootstrap()->getResource('db');
$row = $db->fetchRow('SELECT * FROM something');
Si vous souhaitez ajouter configurable arguments à votre script CLI, jetez un oeil à Zend_Console_Getopt
Si vous trouvez que vous avez le bon code que vous appelez dans les applications MVC, regarder en l'enveloppant dans un objet et l'appel de l'objet en question les méthodes de la MVC et les applications en ligne de commande. C'est le général de bonnes pratiques.
Je viens de voir celui-ci se faire taguer dans mon PC. Si vous êtes tombé sur ce message et utilisez ZF2, cela devient BEAUCOUP plus facile. Modifiez simplement les itinéraires de votre module.config.php comme suit:
/**
* Router
*/
'router' => array(
'routes' => array(
// .. these are your normal web routes, look further down
),
),
/**
* Console Routes
*/
'console' => array(
'router' => array(
'routes' => array(
/* Sample Route */
'do-cli' => array(
'options' => array(
'route' => 'do cli',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'do-cli',
),
),
),
),
),
),
En utilisant la configuration ci-dessus, vous définiriez doCliAction dans votre IndexController.php sous votre module Application. Le lancer est un gâteau, à partir de la ligne de commande:
php index.php do cli
Terminé! Bien plus lisse.
akond la solution ci-dessus est sur la meilleure voie, mais il y a quelques subtilités qui peuvent son script fonctionne pas dans votre environnement. Tenir compte de ces ajustements à sa réponse:
Bootstrap.php
protected function _initRouter()
{
if( PHP_SAPI == 'cli' )
{
$this->bootstrap( 'FrontController' );
$front = $this->getResource( 'FrontController' );
$front->setParam('disableOutputBuffering', true);
$front->setRouter( new Application_Router_Cli() );
$front->setRequest( new Zend_Controller_Request_Simple() );
}
}
Erreur d'initialisation serait probablement barf comme écrit ci-dessus, le gestionnaire d'erreur n'est probablement pas encore instanciée, sauf si vous avez modifié la configuration par défaut.
protected function _initError ()
{
$this->bootstrap( 'FrontController' );
$front = $this->getResource( 'FrontController' );
$front->registerPlugin( new Zend_Controller_Plugin_ErrorHandler() );
$error = $front->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
$error->setErrorHandlerController('index');
if (PHP_SAPI == 'cli')
{
$error->setErrorHandlerController ('error');
$error->setErrorHandlerAction ('cli');
}
}
Vous avez probablement, aussi, veulent munge plus d'un paramètre à partir de la ligne de commande, voici un exemple de base:
class Application_Router_Cli extends Zend_Controller_Router_Abstract
{
public function route (Zend_Controller_Request_Abstract $dispatcher)
{
$getopt = new Zend_Console_Getopt (array ());
$arguments = $getopt->getRemainingArgs();
if ($arguments)
{
$command = array_shift( $arguments );
$action = array_shift( $arguments );
if(!preg_match ('~\W~', $command) )
{
$dispatcher->setControllerName( $command );
$dispatcher->setActionName( $action );
$dispatcher->setParams( $arguments );
return $dispatcher;
}
echo "Invalid command.\n", exit;
}
echo "No command given.\n", exit;
}
public function assemble ($userParams, $name = null, $reset = false, $encode = true)
{
echo "Not implemented\n", exit;
}
}
Enfin, dans votre contrôleur, l'action que vous invoquez utiliser les paramètres qui ont été rendus orphelins par la suppression du contrôleur et l'action de la CLI routeur:
public function echoAction()
{
// disable rendering as required
$database_name = $this->getRequest()->getParam(0);
$udata = array();
if( ($udata = $this->getRequest()->getParam( 1 )) )
$udata = explode( ",", $udata );
echo $database_name;
var_dump( $udata );
}
Vous pouvez ensuite appeler vos CLI la commande suivante:
php index.php Controller Action ....
Par exemple, comme ci-dessus:
php index.php Controller echo database123 this,becomes,an,array
Vous aurez envie de mettre en œuvre une plus robuste, le filtrage de s'échapper, mais, c'est un moyen rapide de bloc de construction. Espérons que cette aide!
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.