CRON s využitím Cli na webhostingu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Bohosu
Člen | 24
+
0
-

Krásné Velikonoce všem! :)

Měl bych na Vás prosbu, protože si už nevím rady a bohužel jsem nikde na fóru nenašel funkční řešení. Rád bych ve své aplikaci využil cron, který bude např. jednou denně něco dělat.

Mám:
nette 2.0.10
php 5.3
hosting Station.cz

Pokud v administraci hostingu zadám url pro cron script:

http://mojedomena.cz/cron/

nebo

http://mojdedomena.cz/index.php Cron:default

tak nefunguje bohužel ani jedno z toho.

I na localhostu příkaz

php http://localhost/aplikace/cron/

či varianta s index.php Cron:default nefunguje. Obojí vrátí chybu: Could not open input file:
http://localhost/aplikace/cron/

Přes příkaz wget samozřejmě problém není, bohužel ale na hostingu jaksi nemám možnost si příkaz zvolit :)

CronPresenter

class CronPresenter extends BasePresenter
{
	public function actionDefault()
	{
		// .... nejaky kod, co by cron mel delat...
                $this->terminate();
	}

}

bootstrap.php

//... originální bootstrap z verze 2.0.10 stable pro php 5.3
if ($container->params['consoleMode']) {
    $container->removeService('httpRequest');
    $container->addService('httpRequest', function() {
        $uri = new UrlScript;
        $uri->scheme = 'http';
        $uri->port = Url::$defaultPorts['http'];
        $uri->host = 'mojedomena.cz';
        $uri->path = '/';
        $uri->canonicalize();
        $uri->path = Strings::fixEncoding($uri->path);
        $uri->scriptPath = '/';
        return new Http\Request($uri, array(), array(), array(), array(), array(), 'GET', null, null);
    });

RouterFactory.php

class RouterFactory
{
	/**
	 * @return Nette\Application\IRouter
	 */
	public function createRouter()
	{

		$router = new RouteList();
		// if ($container->params['consoleMode']) {
		//    $application->allowedMethods = FALSE;
		    $router[] = new CliRouter('Default:default');
                $router[] = new CliRouter(array(
                    'action'    => 'Cron:default',
                ));
		//} else {
		$router[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY);
		$router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
		//}
		return $router;
	}
}

(Vadí, pokud v RouterFactory neuvádím podmínku na params[consoleMode]? )

Můžete mi prosím poradit, co dělám špatně? Případně bych byl nesmírně vděčný za demo pro aktuální verzi nette :) Nemůže být chyba např. v .httacces, resp. nemá tam být něco změměno oproti původnímu?

Děkuji moc!

Editoval Bohosu (1. 4. 2013 21:56)

Filip Procházka
Moderator | 4668
+
0
-

Jsi si jistý, že ti při wgetu spadne požadavek do CLI? Já bych právě neřekl :)

Bohosu
Člen | 24
+
0
-

Dobře, tak při wgetu požadavek asi do CLI nespadne :) , ale jedině tehdy (či při otevření url v prohlížeči) se akce v presenteru provede :)

Bohosu
Člen | 24
+
0
-

Bohužel nefunguje ani metoda, kdy v administraci Cronu na hostingu zadám

http://mojedomena.cz/index.php?presenter=Cron&action=default

Vypadá to, že cron vyžaduje url odkazující přímo na PHP soubor. Vážně nikoho nic nenapadá?

Quinix
Člen | 108
+
0
-

Podle toho jak to rozhraní vypadá to budou nejspíš spouštět wgetem, čili http://mojedomena.cz/cron/ by mělo fungovat…

Přesně ti nejspíš poradí podpora hostingu…

Nox
Člen | 378
+
0
-

Zrovna to taky řešim. Ještě to chce teda zabezpečit, aby to nešlo nijak pustit zvenku

Johny 5
Člen | 5
+
0
-

Zdravím,

dá se nějak spouštět skripty (CRON) jen ze serveru. Napsal jsem routování pomocí CLI a poslal na podporu, ať mi zaregistrují skript. A bohužel oni mohou jen dávat URL (viz. níže). Dá se to nějak zabezpečit, aby šlo zpouštět jen ze serveru? Půjde to poznat z módu? Nebo zabezpečit dle IP? Napadá vás něco?

Děkuji

Dobry den,

skripty v Cronu jsou spousteny pres Lynx, je tedy potreba nam sdelit presnou URL ktery skript chcete spoustet pripadne vcetne promennych.

Priklad:

lynx -source 'http://www.domena.cz/skript.php?prom1=aa?prom2=nn

Potrebuji tedy znat presnou URL.

Upresnete tedy Vas pozadavek.

Dekuji.

thunderbuff
Člen | 164
+
0
-

Pokud umí skripty spouštět jen z URL, tak je zabezpečení problematické. Napadá mě jen přidávat v GETu nějaký tajný token nebo kontrolovat IP. Případně si ještě můžeš dumpnout $_SERVER a mrknout, zda tam není něco, podle čeho by se dalo rozeznat, zda request pochází z „cronu“ nebo ne.

sandal
Člen | 8
+
0
-

Ahoj,

mám velice podobný problém s PHP 5.3.6 a Nette 2.0.13

V podstatě stejný kód (úplně stejný akorát jiné url, názvy akcí atp.) jako Bohosu, který jsem přebral z https://pla.nette.org/…tovani-v-cli

Co potřebuji, je spustit z command line konkrétní funkci. Můj příkaz je:

php.exe D:\workspace\archiv\www\index.php Default:download

Existuje DefaultPresenter a v něm actionDownload()

Vše provádím na localhostu ale funkce se nespustí. I v budoucnu budu mít kompletní hosting ve svých rukách takže enní problé změnit jakékoliv nastavení.

Tušíte kde by mohl být problém, proč nedojde ke spuštění funkce?

thunderbuff
Člen | 164
+
0
-

@sandal: Zkus to popsat nějak lépe. Co se stane? Vyhodí to nějakou chybovou hlášku?

Editoval thunderbuff (4. 1. 2014 3:02)

sandal
Člen | 8
+
0
-

eh, tak po lepším nastavení debugeru jsem zjistil, že se jedná o mojí hloupou chybu. Omylem jsem smazal řádku, která vrací z RouterFactory::createRouter samotný router.

Nicméně měl bych ještě jeden dotaz. V odkazovaném návodu je v routování přímo v bootstrap.php. Tím, že jsem ho přesunul do RouterFactory vyvstává problém (problém nejspíš jenom pro začátečníka v Nette) jak v RouterFactory získat $container abych mohl napsat ekvivalent pro

if ($container->params['consoleMode']) {
    $application->allowedMethods = FALSE;
    $router[] = new CliRouter('Default:default');
} else {
    $router[] = new Route('index.php', 'Default:default', Route::ONE_WAY);
    $router[] = new Route('prihlaseni', 'Default:login');
    $router[] = new Route('<presenter>/<action>[/<id>]', 'Default:default');
}

Díky

jiri.pudil
Nette Blogger | 1029
+
0
-

Vyžádáš si ho jako závislost v konstruktoru:

public function __construct(Nette\DI\Container $container) { ... }

Čistější by ovšem bylo předat si pouze ten parametr, to už ale budeš muset explicitně uvést v configu:

services:
	routerFactory: RouterFactory(%consoleMode%)
public function __construct($consoleMode) { ... }
sandal
Člen | 8
+
0
-

díky, hotovo, funguje ;-)