Auf zwei Datenbanken in einem Dokument zugreifen.

ichhupegerne

Grünschnabel
Liebe Gemeinde,

ich hänge fest. Ich möchte von einem php-dokument auf zwei Datenbanken zugreifen und immer abwechselnd,
mal von der einen, mal von der anderen DB Daten ausgeben.

Bei meinem Versuch klappt es genau ein mal, danach bekomme ich folgenden Fehler:

Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in */htdocs/test/quick_ausgabe.php on line 52

Bis dahin hat das Script Daten einmal von der ersten und einmal von der zweiten DB ausgegeben. Jetzt soll wieder Inhalt von der ersten DB kommen.

Könnt Ihr mal drüber schauhen und mir sagen, was ich falsch mache?

Vielen Dank.

Hier meine verkürzte Version:
PHP:
<?php
// Fehler unterdrücken
error_reporting(E_ALL);

// Verbindung aufbauen, auswählen einer Datenbank
$db_host = "*";
$db_user = "*";
$db_pass = "*";
$db_name = "*";


$dbh = mysql_connect($db_host, $db_user, $db_pass)
    or die("Keine Verbindung möglich: " . mysql_error());

mysql_select_db($db_name) or die("Auswahl der Datenbank fehlgeschlagen");

$abfrage = "SELECT * FROM test WHERE NR = '".$_POST['NR']."'";
$ergebnis = mysql_query($abfrage);

// Verbindung aufbauen, auswählen einer zweiten Datenbank
$mysql_host = "*"; 
$mysql_user = "*";
$mysql_password = "*";
$mysql_db = "*";


$dbh2 = mysql_connect($mysql_host, $mysql_user, $mysql_password)
    or die("Keine Verbindung möglich: " . mysql_error());

mysql_select_db($mysql_db) or die("Auswahl der Datenbank fehlgeschlagen");

$abfrage2 = "SELECT * FROM test2 WHERE NR2 LIKE '".$_POST['NR']."'";
$ergebnis2 = mysql_query($abfrage2);

while ($daten = mysql_fetch_array( $ergebnis, MYSQL_ASSOC)) {
     echo '

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<link rel="stylesheet" type="text/css" href="css_ausgabe.css" />
</head>
<body >
<div id="content">
<div id="spalte1">'.$daten['AUTOKENNZEICHEN'].' - '.$daten['NR'].' von der ersten DB</div>
';}?>
<?php
$ergebnis2 = mysql_query($abfrage2);
while ($daten2 = mysql_fetch_array( $ergebnis2, MYSQL_ASSOC)) {
     echo '
<br /><br />'.$daten2['AUTO_MARKE'].' von der zweiten DB<br /><br />';}?>
<?php
$ergebnis = mysql_query($abfrage);
while ($daten = mysql_fetch_array( $ergebnis, MYSQL_ASSOC)) {
     echo '
<div id="spalte1">Lage: </div>'.$daten['PLZ'].' '.$daten['ORT'].' von der ersten DB<br /><br />

</div><!-- #content -->

<br/>

<br/>


</body>
</html>';}?>
 
Hi sheel,
danke, daß Du mir helfen möchtest, aber Du setzt zu viel voraus.
Ich bin blutiger Anfänger und froh überhaupt so weit gekommen zu sein.

zu 1. Heißt das, ich muß jedes mal im script, wenn die DB wechselt :
Verbindung schließen,
Verbindung öffnen,
Abfrage,
weiter mit html,
Verbindung schließen,
etc.?
Oder wie meinst du das?
Ist mein Queryergebnis verbraucht, wenn ich die DB wechsele?

zu 2: Warum? Ich hab nur kurz gegoogelt. Weil es schneller und sicherer ist?

Aber mysqli dürfte mein Problem doch nicht lösen, oder? Ich habe mich in meinem Script auf diesen: http://www.tutorials.de/php/244501-mehrere-datenbanken-einer-mysql-verbindung-abfragen.html
und diesen: http://www.tutorials.de/php/244542-auf-zweite-db-zugreiffen.html
Beitrag gestützt, die auch mysql benutzen.

Danke für Deine Geduld.
 
Zu 1:
Was du zum Verbindungsaufbu machst ist ja mysql_connect und mysql_select_db,
dann kannst du SQL-Abfragen machen. Soweit alles in Ordnung, aber:
Wenn man mit den Abfragen fertig ist (vor Programmende bzw. vor anderen connect´s)
sollte man die Verbindung auch wieder zu machen (in dem Fall mysql_close).

Auf Abfragenebene gilt das Selbe: Während die Verbindung steht werden sie
mit einem mysql_query "gestartet", dann holt man sich zB. mit mysql_fetch_array
die einzelnen Ergebnisdatensätze, und dann sollte man die Query
aber auch wieder wegräumen (mysql_free_result oder so ähnlich)

In dem Zusammenhang merk ich grad, dass du bei einer Abfrage
zwischen mysql_query und mysql_fetch_array die ganze Verbindung wechselst.
Auch ein möglicher bzw. wahrscheinlicher Problemfaktor.

Vorgegriffen zu MysqlI: Es ist nicht nötig, eine Verbindung zu beenden,
bevor man die nächste aufmacht s(chon beenden wenn fertig,
aber mehrere gleichzeitig offen haben ist möglich).
Dafür muss man dann aber wirklich bei den DB-Funktionen angeben,
um welche Verbindung es gerade geht. MysqlI macht einem das Leben da einfacher...


Zu 2:
Die verlinkten Threads sind von 2006, seit dem hat sich einiges getan.
MysqlI ist quasi der Nachfolger für die "mysql_"-Funktionen
für Verbindungen zwischen PHP und der Datenbank Mysql.

Gründe, warum man die alten Funktionen nicht mehr verwenden sollte:

a) Die "mysql_"-Funktionen werden nicht mehr gewartet (bzw. es ist dabei,
eingestellt zu werden). Das ist der Knackpunkt am Ganzen.
Zurzeit funktionieren sie ja noch, aber PHP und die Datenbank selbst
werden immer weiter entwickelt, geändert, bekommen neue Funktionen usw.
In der Vergangenheit wurden die "mysql_"-Funktionen auch angepasst, wenn es nötig war.
Genau das ist inzwischen zu Ende.

->Heute funktioniert es gut, nächstes Jahr funktioniert es noch irgendwie,
und irgendwann ist man an dem Punkt, wo es mit den neuen PHP/DB-Versionen
einfach nicht mehr klarkommt und gar nichts mehr geht (bzw. nur noch Probleme macht)

Zusätzlich wird es immer weniger selbstverständlich, die Funktionen
bei gemieteten Server von irgendelchen Hostern überhaupt noch installiert zu haben.
Zurzeit gibts nur noch, dmit alte (Vor-MysqlI-) Programme ohne Umschreiben noch funktioneren,
aber irgendwnn ist die Gnadenfrist auch aus (oder das Nicht-mehr-funktionieren kommt zuerst).

b)
Sicherheit.
Die selbe Sache mit Sicherheitsproblemen, falls welche jetzt nach Supportende bekannt werden
(keine Ahnung ob, interessiert mich nicht mehr wirklich)

c) MysqlI hat mehr Funktionen.


Das Internet ist (leider) voll mit alten Anleitungen etc. dazu,
die gut waren als sie geschrieben wurden, heute aber praktich ungültig sind.
Nur gibt es viel zu viel, um das wegzumachen, und viele Anfänger finden dann eben sowas
als Erstes, denken nichts Schlechtes davon und lernen es...
ein Problem, aber keine gute Lösung in Sicht.


Noch etwas zu PDO:
Während MysqlI als Nachfolger zu den alten Funktionen zu verstehen
und auch relativ ähnlich ist, gibt es mit PDO noch eine eigenständige Alternative,
die möglichst DB-unabhängigen Code anstrebt.
Also speziellere Sachen von MySQL eventuell nicht nutzbar,
dafür aber mit einem Programm ohne große Änderungen
auch Postgres, Oracle etc. statt MySQL verwendbar.
 
Vielen Dank für Deine ausführliche Antwort.
Um das Problem der zwei Datenbanken anzugehen, habe ich mich entschlossen,
aufgrund Deiner Erklärungen, das ganze erstmal auf mysqli umzustellen und im
zweiten Schritt die beiden DBs abzufragen.

Da scheitere ich aber schon an der ganz einfachen Ausgabe:

PHP:
<?php
// Fehler unterdrücken
error_reporting(E_ALL);

// Verbindung aufbauen, auswählen einer Datenbank
$db_host = "*";
$db_user = "*";
$db_pass = "*";
$db_name = "*";


$db = mysqli_connect($db_host, $db_user, $db_pass);
if (mysqli_connect_errno()) {
print 'Konnte keine Verbindung zu Datenbank aufbauen, MySQL meldete: '.mysqli_connect_error();
} 

$sql = "SELECT * FROM test WHERE NR = '".$_POST['NR']."'";
$res = mysqli_query($db, $sql);



while ($daten = mysqli_fetch_array($res)) { 
     echo '

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<link rel="stylesheet" type="text/css" href="css_ausgabe.css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">
</script>
</head>
<body onload="initialize'.$daten['NR'].'()">
<div id="content">
<div id="spalte1">'.$daten['AUTOKENNZEICHEN'].' - '.$daten['NR'].'</div>


</body>
</html>';}?>

Ergibt folgende Fehlermeldung:

Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in /*/htdocs/test/quick_ausgabe.php on line 22

Was mache ich falsch?
Danke für Deine Geduld.
 
Die Fehlerprüfung beim connect sollte per Returnwert gehen,
also if(!$db) dann Fehler (und in mysqli_error eine Fehlermeldung)

Zum eigentlichen Problem, technischer Teil:
Hier
PHP:
$sql = "SELECT * FROM test WHERE NR = '".$_POST['NR']."'";
$res = mysqli_query($db, $sql);
hat was nicht geklappt, Grund wahrscheinlich oft Fehler in der SQL-Abfrage.
Deswegen kann man aus $res dann auch nichts fetchen.
Gleich wie beim connect kann man mit if(!$res) auf Fehler prüfen, Fehlermeldung augeben,
und am besten $sql auch noch dazu augeben.

Zum eigentlichen Problem, anderer Teil:
$_POST['NR'] direkt in SQL-Abfragen einbinden ist ein Sicherheitsproblem.
Zwei Eingaben und die resultierenden SQL-Abfragen:
Code:
1234
SELECT * FROM test WHERE NR = '1234'

1'; DROP TABLE test;'
SELECT * FROM test WHERE NR = '1'; DROP TABLE test;''
...wie man sieht, kann man mit den passenden Eingaben viel Blödsinn machen.
Und auch, wenn der Benutzer im Browser nicht direkt beeinflussen kann,
was zu PHP gesendet wird, ist es trotzdem sehr einfach.
(Vor ein paar Monaten gabs hier jemanden, der uns das nicht glauben wollte,
dann hab ich ihm alle Passwörter seiner Benutzer geändert
(Nur Testbenutzer und natürlich vorher angekündigt :)))

Eine mögliche Lösung
PHP:
mysqli_real_escape_string($_POST['NR'])
statt
PHP:
$_POST['NR']
allein einsetzen.

Andere Lösung: Prepared Statements, die allerdings ein größeres Thema für sich sind.
 
Zurück