Nette a PHP-CLI
- Ondrej
- Člen | 110
Chcete nette aplikaci spustit z příkazové řádky např. cronem?
Udělal jsem routu do Nette, která nepracuje s HTTP požadavkem, ale s parametry předané z příkazové řádky.
Prvně je nutné patchnout Application.php (pokud oprava již není
v distribuci)
https://forum.nette.org/cs/2014-php-cli?…
Do bootstrap jako první routu přiřadit
$router[] = new PHPCLIRoute();
syntaxe PHP CLI volání:
$ php document_root/index.php Module:Presenter:Action param1=value param2=value
/**
* Route for PHP CLI
*
* Copyright (c) 2009 Ondrej Novak
*
*/
class PHPCLIRoute extends Object implements IRouter
{
/**
* @param IHttpRequest - interface parameter. We dont use in this method.
* @return PresenterRequest|NULL
*/
public function match(IHttpRequest $httpRequest)
{
if(!Environment::isConsole()) return NULL;
$argv = $GLOBALS['argv'];
if(count($argv) < 2) throw new InvalidStateException('Missing presenter in arguments definition.');
// module:presenter:action parser
$arr = explode(':', $argv[1]);
$action = end($arr);
unset($arr[count($arr)-1]);
$presenter = join(':', $arr);
$params = array();
$params['action'] = $action;
// process script arguments
for($i = 2; $i < count($argv); $i++) {
$p = explode('=', $argv[$i], 2); // $p[0] - variable, $p[1] - value
$params[$p[0]] = $p[1];
}
return new PresenterRequest(
$presenter,
NULL,
$params,
array(),
array(),
array()
);
}
/**
* Constructs absolute URL from PresenterRequest object.
* Empty method for PHP CLI.
* @param IHttpRequest
* @param PresenterRequest
* @return string|NULL
*/
public function constructUrl(PresenterRequest $appRequest, IHttpRequest $httpRequest)
{
return NULL;
}
}
Editoval Ondrej (6. 7. 2009 20:04)
- David Grudl
- Nette Core | 8218
Vyloženě mě nikdy nenapadlo pod Nette dělat CLI aplikace, ale takových požadavků se sešlo víc, tak jsem experimentálně CliRouter přidal, podobný tvému.
$application = Environment::getApplication();
$application->allowedMethods = NULL;
$application->router[] = new CliRouter;
Parsování parametrů by mělo rozumět zápisu třeba:
php.exe index.phpc homepage:default --verbose -user "john doe" "-pass=se cret" /wait
jde na Homepage:default s parametry:
'verbose' => TRUE,
'user' => 'john doe',
'pass' => 'se cret',
'wait' => TRUE
- JakubKohout
- Člen | 92
nevyjde protože když bys to pouštěl přes http požadavek například pomocí WGET, tak máš několik omezení.
- Musel by jsi spřístupnit tyto skripty z venku, a tudíž řešit autentizaci serveru
- Jsi omezem časem pro běh php skriptu, u CLI tomu tak není.
- a zbytečně vytěžuješ apachovský vlákno
- mcmatak
- Člen | 504
ok, chápu
- jasně to řeším nějakým hashem v url, ale ok máš pravdu, na druhou stranu mi to dovoluje ručně spouštět ty skripty, když se třeba z n ějakého důvodu neprovede nebo ho potřebuji provést mimo stanovený čas
- ok rozumím, sice mám povolený set_time_limit ale chápu, že to může být problém
- vytěžuješ apachovský vlákno… asi jedině tady moc nevidím tu výhodu, co to v praxi znamená? je to nějak měřitelné? jestli to zpracovává apache nebo cli?
- JakubKohout
- Člen | 92
Vždyť ty je můžeš pouštět ručně. Stačí dát ./nazev_skriptu.php
No ten dotaz musí jít skrz apache kterej ho musí zpracovat. Například problém když se pokusíš odeslat email a nastane prodleva u odesílání (problém například na u postfixu), tak to sestřelí celej virtualhost (aspoň tohle se mi děje teď na serveru pokud se pokusím odeslat email)
- edke
- Člen | 198
David Grudl wrote:
Vyloženě mě nikdy nenapadlo pod Nette dělat CLI aplikace, ale takových požadavků se sešlo víc, tak jsem experimentálně CliRouter přidal, podobný tvému.
$application = Environment::getApplication(); $application->allowedMethods = NULL; $application->router[] = new CliRouter;
Parsování parametrů by mělo rozumět zápisu třeba:
php.exe index.phpc homepage:default --verbose -user "john doe" "-pass=se cret" /wait jde na Homepage:default s parametry: 'verbose' => TRUE, 'user' => 'john doe', 'pass' => 'se cret', 'wait' => TRUE
Je mozne pre CliRouter predat nejake defaults ? Podla API konstruktor vyzaduje pole, ale mam pocit, ze kod
$application->router[] = new CliRouter(array(
'module' => 'Console',
'presenter' => 'Action',
));
nebude mat ziaden vplyv.
Rad by som totiz mal CLI related presenteri oddelene v samostatnom Module v aplikacii a spustal skript ako
./script.php syncdb --confirm
a nie
./script.php Console:Action:syncdb --confirm
- edke
- Člen | 198
Pomohla by uprava CliRouter napriklad takto:
const PRESENTER_KEY = 'presenter';
/**
* Maps command line arguments to a PresenterRequest object.
* @param IHttpRequest
* @return PresenterRequest|NULL
*/
public function match(IHttpRequest $httpRequest)
{
....
$presenter = $params[self::PRESENTER_KEY];
if ($a = strrpos($presenter, ':')) {
$params[self::PRESENTER_KEY] = substr($presenter, $a + 1);
$presenter = substr($presenter, 0, $a);
}
if ( isset($params['module']))
{
$presenter= $params['module'].':'.ucfirst($presenter);
}
return new PresenterRequest(
$presenter,
'CLI',
$params
);
V cli skripte by sa CliRouter potom nastavil takto:
$application->router[] = new CliRouter(array(
'module' => 'Console',
'presenter' => 'Default',
'action' => 'default'
));
a mame pekne spravanie cli skriptu. pri prvom spusteni bez parametrov sa pusta Console:Default:default, ktory zobrazi napovedu.
Jednotlive akcie potom ako:
./script.php action [options] → Console:Action:default
Editoval edke (16. 2. 2010 15:28)