Ben komut satırından, bazı dosyaları oluşturmak için Zend Framework eylemi çalıştırmak istiyorum. Bu mümkün mü ve ben ZF kullanarak varolan Web proje yapmak için ne kadar bir değişiklik gerekir?
Teşekkürler!
Bu aslında düşündüğünüzden çok daha kolay. MVC yığını ve bir HTTP isteği çağrılır gereksiz kilo kaçınarak önyükleme / uygulama bileşenleri ve mevcut yapılandırmaları, CLI komut ile tekrar edilebilir. Bu wget kullanarak değil bir avantajdır.
Sizin yaptığınız genel index.php olarak komut başlatın:
<?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'));
Daha sonra sadece bir MVC uygulamada olduğu gibi ZF kaynaklarını kullanmaya devam edebilirsiniz:
$db = $application->getBootstrap()->getResource('db');
$row = $db->fetchRow('SELECT * FROM something');
Eğer CLI komut için yapılandırılabilir argümanları eklemek isterseniz, Zend_Console_Getopt bir göz atın
Eğer ayrıca bir nesnenin o kadar sarma ve MVC ve komut satırı uygulamaları hem de o nesnenin yöntemleri arayarak bakmak, MVC uygulamalarında aramak, ortak kodu olduğunu fark ederseniz. Bu, genel iyi bir uygulamadır.
UPDATE
While the solution #1 is ok, sometimes you want something more elaborate. Especially if you are expecting to have more than just one CLI script. If you allow me, I would propose another solution.
Her şeyden önce, sizin bootstrap.php var
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 ());
}
}
Bu yöntem, kendi yönlendirici Application_Router_Cli lehine varsayılan yönlendirici sevk kontrolü mahrum olacaktır.
Web arayüzü için _initRoutes kendi yolları tanımlanmış varsa arada, muhtemelen zaman komut satırı modunda onları nötralize etmek isterim.
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
}
}
Sınıf Application_Router_Cli (Ben özdevinimli_yükle Uygulama önek için açık var sayıyorum) gibi görünebilir:
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;
}
}
Şimdi sadece yürüterek uygulamayı çalıştırabilir
php index.php backup
Bu durumda BackupController denetleyicisi cliAction yöntemi çağrılır.
class BackupController extends Zend_Controller_Action
{
function cliAction ()
{
print "I'm here.\n";
}
}
Hatta önde gitmek ve "cli" eylem her zaman almış, ancak kullanıcı ek bir parametre ile seçilen bir şey, böylece Application_Router_Cli sınıfını değiştirebilirsiniz.
Ve son bir şey. Eğer ekranda herhangi bir html kodunu görmeye olmayacak şekilde komut satırı arayüzü için özel hata işleyicisi tanımlayın
Bootstrap.php yılında
protected function _initError ()
{
$error = $frontcontroller->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
$error->setErrorHandlerController ('index');
if (PHP_SAPI == 'cli')
{
$error->setErrorHandlerController ('error');
$error->setErrorHandlerAction ('cli');
}
}
ErrorController.php yılında
function cliAction ()
{
$this->_helper->viewRenderer->setNoRender (true);
foreach ($this->_getParam ('error_handler') as $error)
{
if ($error instanceof Exception)
{
print $error->getMessage () . "\n";
}
}
}
Yukarıda akond çözümü iyi yolda olduğunu, ancak onun script ortamda çalışmak olmayabilir bazı incelikleri vardır. Onun cevabını bu tweaks düşünün:
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() );
}
}
Eğer varsayılan yapılandırma değiştirildi sürece Init hata muhtemelen kusmuğu yukarıda yazıldığı gibi, hata işleyicisi muhtemelen henüz örneği değil olurdu.
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');
}
}
Muhtemelen, Ayrıca, komut satırından birden fazla parametre gizleyin istiyorum, burada temel bir örnek:
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;
}
}
Son olarak, kontrolör, sen CLI yönlendirici tarafından denetleyici ve eylem kaldırılması ile yetim kalmıştır params faydalanmak çağırmak hareket:
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 );
}
Daha sonra ile CLI komutu çağırmak olabilir:
php index.php Controller Action ....
Örneğin, yukarıdaki gibi:
php index.php Controller echo database123 this,becomes,an,array
Bunu hızlı bir yapı blok, daha güçlü bir filtreleme / kaçışa uygulamak istiyorum, ama olacak. Bu yardımcı olur umarım!
Sadece bu benim CP etiketlendi gördüm. Bu yazı üzerine tökezledi ve ZF2 kullanıyorsanız, çok daha kolay kazanılmış. Sadece bu yüzden gibi module.config.php 's yolları düzenleyin:
/**
* 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',
),
),
),
),
),
),
Yukarıdaki yapılandırma kullanarak, Uygulama modülü altında IndexController.php içinde doCliAction tanımlayacaktır. Çalışan komut satırından, kek:
php index.php do cli
Done! Way smoother.
hata özel hata denetleyicisi tarafından işlenir değil dışında akond fikir, harika çalışıyor.
public function cliAction() {
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
foreach ($this->_getParam('error_handler') as $error) {
if ($error instanceof Exception) {
print "cli-error: " . $error->getMessage() . "\n";
}
}
}
ve Application_Router_Cli yılında yankı kapalı Görüşlerinizi ve bildirimde die
public function assemble($userParams, $name = null, $reset = false, $encode = true) {
//echo "Not implemented\n";
}
Sen sadece komut satırından normal şekilde PHP kullanabilirsiniz. PHP bir komut dosyası çağırın ve ya da komut eylem ayarlarsanız o zaman istersen çalıştırabilirsiniz.
It would be quite simple really. Its not really the intended usage, however this is how it could work if you wanted to.
Örneğin
php script.php
Burada okuyun: http://php.net/manual/en/features.commandline.php
OS Linux ise wget komutunu kullanabilirsiniz. Örneğin:
wget http://example.com/controller/action
Bkz http://linux.about.com/od/commands/l/blcmdl1_wget.htm
GÜNCELLEME:
Böyle basit bir bash betiği yazabilirsiniz:
if wget http://example.com/controller/action
echo "Hello World!" > /home/wasdownloaded.txt
else
"crap, wget timed out, let's remove the file."
rm /home/wasdownloaded.txt
fi
Sonra PHP yapabilirsiniz:
if (true === file_exists('/home/wasdownloaded.txt') {
// to check that the
}
Umarım bu yardımcı olur.