Runonce: Unterschied zwischen den Versionen
Aus Contao Community Documentation
(→Modulbasierte runonce.php) |
(→Probleme) |
||
Zeile 100: | Zeile 100: | ||
Andererseits könnte man diesen Abschnitt immer im Modul lassen und nur durch Setzen der Variablen $runonceFile bestimmen, ob es was zu tun gibt oder nicht. | Andererseits könnte man diesen Abschnitt immer im Modul lassen und nur durch Setzen der Variablen $runonceFile bestimmen, ob es was zu tun gibt oder nicht. | ||
− | =Probleme= | + | ==Probleme== |
− | Einen kleinen Nebeneffekt hat die ganze Sache. Egal ob die funktions- oder objektorientierte Variante, es kommt zu einer Fehlermeldung, sobald man die Datenbank Instanz nutzt.<br /> | + | Einen kleinen Nebeneffekt hat die ganze Sache. Egal ob die funktions- oder objektorientierte Variante, es kommt öfters zu einer Fehlermeldung, sobald man die Datenbank Instanz nutzt.<br /> |
Am Ende der Seite erscheint die Meldung:<br /> | Am Ende der Seite erscheint die Meldung:<br /> | ||
Fatal error: Exception thrown without a stack frame in Unknown on line 0 | Fatal error: Exception thrown without a stack frame in Unknown on line 0 | ||
Das Script selbst wird dabei ohne Probleme abgearbeitet, auch das Backend selbst wird dadurch nicht gestört.<br /> | Das Script selbst wird dabei ohne Probleme abgearbeitet, auch das Backend selbst wird dadurch nicht gestört.<br /> | ||
− | {{ | + | <br /> |
+ | Durch langes experimentieren bin ich auf eine Lösung gekommen, die zumindest bei mir funktioniert.<br /> | ||
+ | Dazu wird der <nowiki>include</nowiki> der runonce Datei mittels try - catch gekapselt. Wichtig dabei ist mit <nowiki>getMessage</nowiki> die Nachrichten auszulesen.<br /> | ||
+ | Hier nun der geänderte Code:<br> | ||
+ | <pre> | ||
+ | $runonceFile = 'system/modules/MODULNAME/config/runonce.php'; // relativ zu TL_ROOT | ||
+ | if (file_exists(TL_ROOT . '/' . $runonceFile)) | ||
+ | { | ||
+ | $GLOBALS['runonce']['MODULNAME'] = false; | ||
+ | |||
+ | try | ||
+ | { | ||
+ | include(TL_ROOT . '/' . $runonceFile); | ||
+ | } | ||
+ | catch (Exception $e) { $errors[] = $e->getMessage(); } | ||
+ | |||
+ | if ($GLOBALS['runonce']['MODULNAME'] === false) | ||
+ | { | ||
+ | $objFiles = Files::getInstance(); | ||
+ | $objFiles->delete($runonceFile); // hier wird intern ein "TL_ROOT/" vorgesetzt | ||
+ | //nun wieder neu anlegen mit neuem Inhalt | ||
+ | $objFile = new File($runonceFile); // hier wird intern ein "TL_ROOT/" vorgesetzt | ||
+ | $objFile->write("<?php \$GLOBALS['runonce']['MODULNAME'] = true; ?>"); | ||
+ | $objFile->close(); | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
---- | ---- | ||
− | --[[Benutzer:BugBuster|BugBuster]] | + | --[[Benutzer:BugBuster|BugBuster]] 22:49, 17. Jul. 2010 (CEST) |
Version vom 17. Juli 2010, 21:49 Uhr
betrifft | |
---|---|
TYPOlight Version | ab 2.7 |
Contao Version | ab 2.9 |
Live Update nutzt diese, die Extensions nutzen diese auch: die Datei TL_ROOT/system/runonce.php
Diese Datei tut genau das, was der Name schon vermuten lässt. Sie wird nur einmal ausgeführt und anschließend gelöscht.
Bei jedem Seitenaufruf wird dazu geprüft, ob diese vorhanden ist und ggf. ausgeführt.
In der Extension legt man diese Datei dann ab im Pfad wie wie oben bereits angegeben.
Inhaltsverzeichnis
Anwendungsbeispiele
Löschen einer Datei
<?php @error_reporting(0); @ini_set("display_errors", 0); try { // Datei relativ zu TL_ROOT $file = 'system/modules/demo/delete_me.gif'; $objFiles = Files::getInstance(); $objFiles->delete($file); } catch (Exception $e) { $errors[] = $e->getMessage(); } ?>
Die Fehlerausgaben, sollte es welche geben, werden in diesem Beispiel unterdrückt.
Datenbank Insert / Update
<?php @error_reporting(0); @ini_set("display_errors", 0); $objDatabase = Database::getInstance(); // // Update database try { $objDatabase->execute("UPDATE `tl_demo_table` SET `demo_counter`=0 WHERE `demo_browser`='Unknown'"); } catch (Exception $e) { $errors[] = $e->getMessage(); } // // Insert database try { $objDatabase->execute("INSERT INTO `tl_demo_table` (`id`, `demo_counter`) VALUES (0, '10')"); } catch (Exception $e) { $errors[] = $e->getMessage(); } ?>
Datenbank Insert, OOP Variante
Quelle: Forum.
<?php class RunonceJob extends Frontend { public function __construct() { parent::__construct(); } public function run() { $arrInsert=array( 'action' => 'runonce', 'text' => 'runonce' ); $this->Database->prepare("INSERT INTO tl_log %s")->set($arrInsert)->execute(); } } $objRunonceJob = new RunonceJob(); $objRunonceJob->run(); ?>
Hinweis
Achtung: Vorsicht damit bei Extensions mit Abhängigkeiten zu weiteren Extensions. Bringen 2 Extensions jeweils eine runonce.php mit, wird nur eine ausgeführt! |
Hier ist der Author nicht sicher, ob die erste oder die letzte davon.
Modulbasierte runonce.php
Den nachfolgenden Code in die config.php des eigenen Modules einfügen. Den Pfad anpassen, "MODULNAME" durch den Verzeichnisnamen des eigenen Moduls ersetzen und eine runonce.php im config Verzeichnis erstellen.
Diese runonce.php wird beim nächsten Seitenaufruf einmalig ausgeführt und danach gelöscht.
$runonceFile = '/system/modules/MODULNAME/config/runonce.php'; if (file_exists(TL_ROOT . $runonceFile)) { include(TL_ROOT . $runonceFile); $objFiles = Files::getInstance(); $objFiles->delete($runonceFile); }
Nachteil dieser Variante, die ER Verwaltung meckert, das Modul sei unvollständig, da nun eine Datei fehlt.
Idee: die Datei nicht löschen sondern überschreiben:
$runonceFile = 'system/modules/MODULNAME/config/runonce.php'; // relativ zu TL_ROOT if (file_exists(TL_ROOT . '/' . $runonceFile)) { $GLOBALS['runonce']['MODULNAME'] = false; include(TL_ROOT . '/' . $runonceFile); if ($GLOBALS['runonce']['MODULNAME'] === false) { $objFiles = Files::getInstance(); $objFiles->delete($runonceFile); // hier wird intern ein "TL_ROOT/" vorgesetzt //nun wieder neu anlegen mit neuem Inhalt $objFile = new File($runonceFile); // hier wird intern ein "TL_ROOT/" vorgesetzt $objFile->write("<?php \$GLOBALS['runonce']['MODULNAME'] = true; ?>"); $objFile->close(); } }
Wobei man nun die file_exists Prüfung weglassen könnte.
Andererseits könnte man diesen Abschnitt immer im Modul lassen und nur durch Setzen der Variablen $runonceFile bestimmen, ob es was zu tun gibt oder nicht.
Probleme
Einen kleinen Nebeneffekt hat die ganze Sache. Egal ob die funktions- oder objektorientierte Variante, es kommt öfters zu einer Fehlermeldung, sobald man die Datenbank Instanz nutzt.
Am Ende der Seite erscheint die Meldung:
Fatal error: Exception thrown without a stack frame in Unknown on line 0
Das Script selbst wird dabei ohne Probleme abgearbeitet, auch das Backend selbst wird dadurch nicht gestört.
Durch langes experimentieren bin ich auf eine Lösung gekommen, die zumindest bei mir funktioniert.
Dazu wird der include der runonce Datei mittels try - catch gekapselt. Wichtig dabei ist mit getMessage die Nachrichten auszulesen.
Hier nun der geänderte Code:
$runonceFile = 'system/modules/MODULNAME/config/runonce.php'; // relativ zu TL_ROOT if (file_exists(TL_ROOT . '/' . $runonceFile)) { $GLOBALS['runonce']['MODULNAME'] = false; try { include(TL_ROOT . '/' . $runonceFile); } catch (Exception $e) { $errors[] = $e->getMessage(); } if ($GLOBALS['runonce']['MODULNAME'] === false) { $objFiles = Files::getInstance(); $objFiles->delete($runonceFile); // hier wird intern ein "TL_ROOT/" vorgesetzt //nun wieder neu anlegen mit neuem Inhalt $objFile = new File($runonceFile); // hier wird intern ein "TL_ROOT/" vorgesetzt $objFile->write("<?php \$GLOBALS['runonce']['MODULNAME'] = true; ?>"); $objFile->close(); } }
--BugBuster 22:49, 17. Jul. 2010 (CEST)