Joomla! Forum Schweiz wird Teil der D-A-CH Community

Nach vielen Jahren als zentrale Anlaufstelle für Fragen rund um Joomla! in der Schweiz wird das Joomla! Forum Schweiz künftig als Archiv weitergeführt.

Die Joomla!-Communities aus Deutschland, Österreich und der Schweiz arbeiten heute enger denn je zusammen. Deshalb bündeln wir künftig auch den deutschsprachigen Support und Austausch an einem gemeinsamen Ort im Joomla! D-A-CH Forum.

Für neue Fragen, Diskussionen und den Austausch mit der Community nutzt bitte ab sofort:

forum.joomla.de

Das Joomla! Forum Schweiz bleibt weiterhin bestehen und wird als Archiv im Lesemodus erhalten. Die vielen Beiträge, Lösungen und Erfahrungen aus den vergangenen Jahren bleiben damit weiterhin zugänglich und über die Suche auffindbar.

Wir bedanken uns herzlich bei allen Mitgliedern, Moderatoren und Helfern, die das Schweizer Joomla! Forum über viele Jahre mit ihrem Wissen und ihrem Engagement geprägt haben.

Wir sehen uns im Joomla! D-A-CH Forum!

Verbindung zu einer externen DB

  • strubi
  • Autor
  • Neues Mitglied
  • Neues Mitglied
Mehr
23 Apr. 2010 21:14 #26017 von strubi
Verbindung zu einer externen DB wurde erstellt von strubi
Hallo zusammen
Habe da ein kniffliges Problem. Ich schreibe eine Komponente die eine Verbindung zu einer Groopware herstellt. In der Groopware werden z.B. Termine, Adressen, Podcast etc. verwaltet([url:2n2h1bfh] www.churchtool.org [/url]). Nun möchten wir mit der Komponente z.B. die Termine als Veranstaltungen in unserer Joomla! Homepage anzeigen.

Die Groopware ist eigentlich auch eine Homepage und dahinter verbirgt sich auch eine MySQL Datenbank. Wenn nun die Groopware und Joomla! in der gleichen DB gespeichert ist, habe ich kein problem. Schwierig wird es erst dann, wenn die Groopware eine eigene DB besitzt. Dann kann ich nämlich nicht mehr so einfach darauf zu greifen. Diese Situation ist auch öfters der Fall, da die Groopware nicht unbedingt am gleichen Ort gehostet wird wie die Homepage.

So, nun zu meinen Problemen.
In der Konfiguration der Komponente kann ich nun angeben ob die Groopware Tabellen in der gleichen DB liegt wie Joomla! Nun möchte ich eine Funktion schreiben die für alle Models zur Verfügung steht. In dieser Funktion wird geprüft ob die "interne" oder "Externe" Datenbank angesprochen wird. Der Funktion gebe ich die SQL Abfrage mit und die liefert mir dann diese Abfrage aus der richtigen DB aus. Das Ziel ist, dass ich dieser Funktion nur noch die SQL Abfrage weiter gebe (und sonst ev. noch ein zwei Parameter) und dann spuckt die Funktion diese Daten aus. Wo muss ich diese Funktion speichern, dass sie von allen Models aufgerufen werden kann?
(Ich habe nämlich nicht lust, die Abfrage "intern/Extern" für jede Abfrage neu zu schreiben...)

Die zweite Frage ist, wie ich die Funktion schreiben muss. Habe da noch einen Knoten... Habe mal einen Code aufgesetzt doch der funktioniert nicht richtig. Hier also einmal der Code:
Code:
function koolDb ($koquery,$list) { // Parameter laden $params = &JComponentHelper::getParams( 'com_jkool' ); //SQL Abfragen wenn kOOL Tabellen sich nicht in der gleichen DB wie Joomla! befindet. if ($params->get('JK_DB_INT') == 1) { return 'DB Extern'; //Testeintrag um zu prüfen ob die Prüfung erfolgreich verlaufen ist } //SQL Abfragen wenn kOOL Tabellen sich in der gleichen DB wie Joomla! befindet. else { $this->_db->setQuery( $koquery ); if ($list =='list') { //Gibt die Abfrage als Liste aus $this->_data = $this->_getList( $koquery ); } else { //Gibt den ersten Datensatz aus $this->_data = $this->_db->loadObject(); } // Daten ausgeben return $this->_data; } }
Es ist gut möglich, dass ich da ne Menge falsch gemacht habe. Ich habe früher ASP entwickelt und dann eine mehrjährige Pause eingelegt. Bin nun erst kürzlich auf PHP umgestiegen und muss mich nun noch ein wenig einarbeiten.

Also 1. wo soll ich diese Funktion speichern und 2. was mach ich falsch?
Herzlichen Dank für Euere Hilfe, erspart mir einige Nächte ;)
Gruss strubi
  • DietmarH
  • Neues Mitglied
  • Neues Mitglied
Mehr
23 Apr. 2010 23:51 #26019 von DietmarH
DietmarH antwortete auf Re: Verbindung zu einer externen DB

strubi schrieb: Diese Situation ist auch öfters der Fall, da die Groopware nicht unbedingt am gleichen Ort gehostet wird wie die Homepage.

Dann kannst du das sowieso vergessen. Kein Hoster, zu dem man Vertrauen haben kann, läßt einen Zugriff von außen auf die DB zu.
Der sinnvollste Weg wäre, die Termine in der Groupware als XML anzubieten.
  • strubi
  • Autor
  • Neues Mitglied
  • Neues Mitglied
Mehr
24 Apr. 2010 18:26 #26027 von strubi
strubi antwortete auf Re: Verbindung zu einer externen DB
oh... das habe ich ganz vergessen... Nun wie währe es, die DB's beide beim gleichen Host aber in verschiedenen DB's Gespeichert wird? Kann auch sinn machen, wenn man es gerne übersichtlich hat. Hat auch den Vorteil dass wenn man die DB's anpasst und dabei ein Fehler passiert nicht gleich alles hops geht (Natürlich werden auch backups gemacht...)
Mehr
24 Apr. 2010 21:01 #26029 von Tribal6
Tribal6 antwortete auf Re: Verbindung zu einer externen DB
Hi

Hier mal ein Anfang als einfache Funktion mit statischer Variable, damit auch bei mehreren Aufrufen der Funktion nur einmal mit der Datenbank verbunden wird:
Code:
function &getKoolDbObject () { static $jKoolDbInstance = false; $params = JComponentHelper::getParams( 'com_jkool'); if ($params->get('externaldb') == '1' and $jKoolDbInstance === false) { // mit externer DB verbinden und DB-Ojekt returnen: $option['driver'] = 'mysql'; // DB-Treiber $option['host'] = $params->get('external_host'); // DB-Host $option['user'] = $params->get('external_user'); // DB-Benutzername $option['password'] = $params->get('external_pass'); // DB-Passwort $option['database'] = $params->get('external_db_name'); // Datenbank Name $option['prefix'] = $params->get('external_db_prefix'); // Prefix (kann auch leer sein) if(!$jKoolDbInstance = & JDatabase::getInstance( $option )) { // Fehler in der Datenbankverbindung: $errorMsg = JDatabase->getError(); // throw new Exception() oder JError::raiseError(); o.ä. return false; } elseif ($jKoolDbInstance === false) { // verbinden mit 'interner' Joomla-Datenbank if (!$jKoolDbInstance = &JFactory::getDBO()) { // Fehlerbehandlung fehlt noch; } } return $jKoolDbInstance ; }

Dein Datenbank-Objekt (intern oder extern) erhälst du dann mit
$db = &getKoolDbObject();

Die jeweiligen 'Eintritts-Dateien' für eigene Komponenten sind:

Frontend: JOOMLAROOT/components/com_KOMPONENTENNAME/KOMPONENTENNAME.php
Backend: JOOMLAROOT/administrator/components/com_KOMPONENTENNAME/admin.KOMPONENTENNAME.php

Diese Dateien eignen sich für includes und Deklarationen oder auch für eine Auto-Loader Funktion, da sie die 'Eintrittspunkte' für (d)eine Erweiterung sind. Eine gebräuchliche Vorgehensweise ist auch jeweils für eine Komponente eine Helper-Klasse mit statischen Hilfs-Funktionen zu schreiben, in die dann solche Dinge wie die hier reinkommen, und so global in einer Erweiterung vergügbar sind.

Prost
Roger

Tue das, was du kannst, mit dem was du hast, da wo du bist.
  • strubi
  • Autor
  • Neues Mitglied
  • Neues Mitglied
Mehr
26 Apr. 2010 12:19 #26046 von strubi
strubi antwortete auf Re: Verbindung zu einer externen DB
Hallo Roger
Danke für die Funktion, sieht gut aus, komme aber noch nicht ganz zurecht.

Im Model in dem ich die Daten auslese habe ich nun folgende Abfrage:
Code:
function &getDatakool () { //Laden der Datbenbank $db = &getKoolDbObject(); //Laden der Daten $query = ' SELECT id, name FROM ko_eventgruppen '; $db->setQuery( $query ); $this->_data = $this->_getList( $query ); // Daten ausgeben return $this->_data; }
Wenn ich nun die Einstellungen so gesetzt habe, dass die Daten aus der "internen" DB gelesen werden, so funktioniert alles. Es wir nun eine Liste mit der ID und den Namen der Evengruppen ausgegeben. Alles Bestens!
Wenn ich nun aber die Datenbank auf "Extern" setze so kommt der Fehler:
"Notice: Only variable references should be returned by reference in(...)Fatal error: Call to a member function setQuery() on a non-object in(...)"
Die Parameter (Host, Username etc.) sind richtig, habe ich sogar schon manuell eingegeben, kam der gleiche Fehler. Die SQL Abfrage ist bei beiden DB ja die gleiche, also woran kann der Fehler liegen?

Dann habe ich noch eine Frage zum Code:
Für was braucht man 3 Gleichheitszeichen (z.B. ...and $jKoolDbInstance === false...) (Wie gesagt, bin mich zur zeit noch am einarbeiten ins PHP...)

Dann noch eine Fragen zu den Helpers:
Ich würde gerne die Abfrage in die Helpers verpacken. Finde das noch praktisch wenn das Zeugs in verschiedenen Ordnern abgelegt ist. Die Frage ist nur, wie ich das nun lade. Ich habe mal bei einer anderen Komponente abgekuckt, komme aber nicht ganz nach.

Ich habe einen Ordner namens "Helpers" angelegt und darin eine Datei "komponentenname.php". Die Datei fängt nun im Meinem Falle mit folgendem Code an:
Code:
// Helpersklasse für jkool class JkoolHelper { ... }
Nun, wie binde ich diese Klasse nun ein, dass sie von allen Seiten gelesen werden kann? Ich habe mal versucht, generell die Datei mit folgendem Code zu laden:
Code:
require_once(JPATH_COMPONENT.DS.'helpers'.DS.'jkool.php');
Doch das funktioniert noch nicht ganz... Was muss ich noch tun?
Herzliche Grüsse
Strubi
Mehr
26 Apr. 2010 13:35 #26050 von Tribal6
Tribal6 antwortete auf Re: Verbindung zu einer externen DB

"Notice: Only variable references should be returned by reference in(...)

Mein Fehler: Nimm das '&' weg bei der Funktionsdeklaration und beim Funktionsaufruf.

Fatal error: Call to a member function setQuery() on a non-object in(...)

Da wird versucht, eine Objektmethode aufzurufen, doch das Objekt selbst fehlt. Das heisst, es wurde kein Datenbankobjekt aus der Funktion zurückgegeben. Lass dir doch mal die $errorMsg ausgeben.
(throw new Exception($errorMsg);)
Ich hab es ja angedeutet, das die Fehlerbehandlung da noch einzubauen ist. Und die ist u.a. auch abhängig davon, wie du das implementierst.

Und in deinem Code hast du das DB-Objekt in
$db = &getKoolDbObject();
Holst die Daten aber mit $this->_getList( $query );
also über ein anderes Datenbank-Objekt.

Und die drei Gleichheitszeichen, da wird nicht nur der Inhalt, sondern auch der Datentyp verglichen:
--ALTER LINK WURDE ENTFERNT--

Und das Einbinden der Datei:

Doch das funktioniert noch nicht ganz

Ist einbisschen vage formuliert. Hast du da eine PHP-Fehlermeldung?

Tue das, was du kannst, mit dem was du hast, da wo du bist.
  • strubi
  • Autor
  • Neues Mitglied
  • Neues Mitglied
Mehr
26 Apr. 2010 14:51 #26052 von strubi
strubi antwortete auf Re: Verbindung zu einer externen DB
Hat funktioniert! Saumässig cool! :) )
Nachdem ich die "&" gelöscht hatte, funktionierte nun die Externe DB und die Interne nicht mehr. Habe dann gemerkt dass der Else Befehl noch falsch liegt, der muss eine Instanz höher sein...

Noch ne Frage wegen der Fehlermeldungen. Die funktionieren auch noch nicht richtig. Sobald ich das habe stelle ich den code noch einmal sauber hier rein...
Ich programmiere die Fehlermeldung folgendermassen:
Code:
if(!$jKoolDbInstance = & JDatabase::getInstance( $option )) { // Fehler in der Datenbankverbindung: $errorMsg = JDatabase->getError(); throw new Exception($errorMsg); return false; }

Nun kommt der Fehler "Parse error: syntax error, unexpected T_OBJECT_OPERATOR in(...)" Die Zeile
Code:
$errorMsg = JDatabase->getError();
hat er scheinbar gar nicht gerne. Was muss ich da tun?

Noch wegen der Helpers klasse:
Das einbinden der Datei funktioniert schon. Doch irgend wie muss ich doch die helpers Class aufrufen. Wenn ich nun die Funktion zur DB auswahl, die nun ja unter admin.jkool.php funktioniert in die Helpersklasse verschiebe kommt folgende Rückmeldung:
Code:
Fatal error: Call to undefined function getkooldbobject() in(...)
Sprich er findet die Funktion ja nicht...
Oder?
Mehr
26 Apr. 2010 21:37 #26057 von Tribal6
Tribal6 antwortete auf Re: Verbindung zu einer externen DB
Ok, hört sich schon mal gut an....

Fehlermeldung:
Klar geht das nicht so, ist ja eine statische Funktion, sorry.

Guckst du mal
--ALTER LINK WURDE ENTFERNT--
Und wenn du dich da einbisschen durchklickst, wirst du sehen, das du mit JDatabase::getInstance($option) entweder ein JDatabase-Objekt zurückbekommst, oder aber ein JExcption-Object (wenn mich jetzt nicht verguckt hab).
Also prüfen, was für ein Objekt zurückgegeben wird:
if ($db instanceof JDatabase) {
// alles paletti
} elsif ($db instanceof JException) {
// Fehler: $db ist JException-Objekt
// --ALTER LINK WURDE ENTFERNT--
// also nicht JDatabase->getMessage() sondern
$db->getMessage();
} else {
// Computer abstellen und ein Bier trinken gehen ;)
}

Soweit mal die Theorie dazu (testen musst du)

Helperklasse:

class JKoolHelper {
public static function getJKoolDb() {
.......
}
}

Wenn die richtig eingebunden ist, folgendermassen Aufrufen:
$db = JKoolHelper::getJKoolDb();

Cheers
Roger

Tue das, was du kannst, mit dem was du hast, da wo du bist.
  • strubi
  • Autor
  • Neues Mitglied
  • Neues Mitglied
Mehr
11 Mai 2010 14:13 #26178 von strubi
strubi antwortete auf Re: Verbindung zu einer externen DB
Hallo zusammen
Habe ja versprochen, den fertigen Code noch einmal hier zu posten. Nun funktioniert alles tipp topp!
@roger, wenn es möglich währe würde ich Dir glatt eine Schokolade rüber Mailen. Aber leider geht das heute noch nicht. Bin Dir echt dankbar für Deine Hilfe!

Hier also der Code:
com_jkool/helpers/jkool.php
Code:
// Helpersklasse für meine Jkool class JkoolHelper { public static function getJKoolDb() { static $jKoolDbInstance = false; $params = JComponentHelper::getParams( 'com_jkool'); if ($params->get('JK_DB_INT') == '1' and $jKoolDbInstance === false) { // mit externer DB verbinden und DB-Ojekt returnen: $option['driver'] = 'mysql'; // DB-Treiber $option['host'] = $params->get('JK_HOST'); // DB-Host $option['user'] = $params->get('JK_DB_USER'); // DB-Benutzername $option['password'] = $params->get('JK_DB_PASSWORT'); // DB-Passwort $option['database'] = $params->get('JK_DB'); // Datenbank Name $option['prefix'] = $params->get(''); // Prefix (kann auch leer sein) if(!$jKoolDbInstance = & JDatabase::getInstance( $option )) { // Fehler in der Datenbankverbindung: JError::raiseError( 500, $jKoolDbInstance->stderr('Load Data Problem') ); return false; } } elseif ($jKoolDbInstance === false) { // verbinden mit 'interner' Joomla-Datenbank if (!$jKoolDbInstance = &JFactory::getDBO()) { // Fehler in der Datenbankverbingung JError::raiseError( 500, $jKoolDbInstance->stderr('Load Data Problem') ); } } return $jKoolDbInstance ; } }
Bei der Felerprogrammierung bin ich noch nicht ganz durch. Weis nicht ob das was ich hier geschrieben habe stimmt, kann Feler auch nicht gut testen, denn es läuft ja ;)

com_jkool/admin.jkool.php
Code:
// Einlesen des Helpers require_once(JPATH_COMPONENT.DS.'helpers'.DS.'jkool.php');

Aufrufen der Klasse unter
com_jkool/models/beispiel_model.php
Code:
/******************************************************************* * Daten aus den kOOL Tabellen. *******************************************************************/ /** * Auslesen der Termingruppen aus der kOOL Datenbank */ function &getDatakool () { //Laden der Datbenban $db = JkoolHelper::getJKoolDb(); //Laden der Daten $query = ' SELECT id, name FROM ko_tabellenname '; $db->setQuery( $query ); $jkc_data = $db->loadObjectList( ); // Daten ausgeben return $jkc_data; }

Herzlichen Dank also noch eimal!
Gruss Strubi
Mehr
11 Mai 2010 14:23 #26179 von Tribal6
Tribal6 antwortete auf Re: Verbindung zu einer externen DB
Aloha Strubi

...würde ich Dir glatt eine Schokolade


...ich steh ja nicht so auf Süsses, aber wie wäre es mal mit einem Bierchen? Am nächsten Joomla.ch Event? ;)

Tue das, was du kannst, mit dem was du hast, da wo du bist.
Moderatoren: Tribal6, RePao, Dragonlord, Chris Hoefliger, pascale, adiheutschi.ch
Powered by Kunena Forum

Joomla! Verband Schweiz - Mitglied werden