MYSQLI_Query uit 2 databases

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mar kla

mar kla

05/09/2024 20:31:50
Quote Anchor link
Voor twee websites gebruik ik twee databases

Nieuws (bevat nieuwsberichten)
Wedstrijden (bevat wedstrijd gegevens)


In de Wedstrijden database is ook een w.nieuwsbericht_id opgenomen over deze wedstrijd.
Het w.nieuwsbericht_id is dezelfde waarde als het n.nieuwsbericht_id die in de Nieuws database staat en dat het wedstrijdverslag mbt die wedstrijd bevat.

Ieder w.wedstrijd_id heeft NULL of maximaal één nieuwsbericht_id

In De Nieuws database staat geen n.wedstrijd _id.
Want niet ieder nieuwsbericht is ook een wedstrijdverslag.


Nu heb ik het voor elkaar dat ik via een:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
mysqli_query( $dbconnection_W, select.....

Uit de Wedstrijden database wordt gehaald.

Die gegevens uit de Wedstrijden database plaats ik op de pagina: MATCHPAGE van de Nieuws website.

Dat gaat allemaal goed.

MAAR..
Uit de wedstrijden database komt per wedstrijd dus ook een w.nieuwsbericht_id.
Via een function zou ik graag de n.permalink uit de Nieuws database willen selecteren. Daarmee kan ik dan bij elke wedstrijd een anchorlink naar het bijbehorende nieuwsbericht (lees wedstrijd verslag) maken.

Daarvoor heb ik deze function bedacht:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
128 function show_permalink($id)
129 {
130 $sql_permalink = mysqli_query($dbconnection_N,
131 "SELECT
132 n.permalink as permalink
133 FROM newsitems n
134 WHERE n.NewsItem_ID=".$id."
135 AND  n.NewsItem_Publist='Y'")
136 or die (mysqli_error($dbconnection_N));
137
138 while($record = mysqli_fetch_array($sql_permalink))
139 {
140 $permalink = $record['permalink'];
141 return $permalink;
 


Deze function roep ik aan in de "MATCHPAGE" van de Nieuws website:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5

If($record['w.nieuwsbericht_id']==0)
    {($MatchReport= $NO_MatchReport_Icon );}
    else
    {($MatchReport='<a href="/article/'.show_permalink($record['w.nieuwsbericht_id].) '">'.$MatchReport_Icon.'</a>');}




Wat er nu gebeurd is dat ik een foutmelding:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
Undefined variable: dbconnection_N in functions op regel 134 en 138 van de function show_permalink


Ik snap dat de dbconnection_W het gebruik van de dbconnection_N blokkeert.

hopelijk heb ik e.e.a. een beetje begrijpelijk genoteerd
 
PHP hulp

PHP hulp

16/09/2024 20:48:57
 
- Ariën  -
Beheerder

- Ariën -

05/09/2024 21:42:55
Quote Anchor link
Is het niet mogelijk om alles te migreren naar één database?
Gewijzigd op 05/09/2024 21:44:36 door - Ariën -
 
Mar kla

mar kla

05/09/2024 22:42:55
Quote Anchor link
De database en de websites zijn juist (jaren geleden al) gesplitst. :-)
 
- Ariën  -
Beheerder

- Ariën -

05/09/2024 23:38:35
Quote Anchor link
En met welke reden? met Mysqli heb je een handige linkidentifier, maar toch is het schakelen tussen meerdere databases wel een gedoe....
Gewijzigd op 05/09/2024 23:39:22 door - Ariën -
 
Willem vp

Willem vp

06/09/2024 01:55:57
Quote Anchor link
In show_permalink() wordt $dbconnection_N niet geïnitialiseerd, vandaar die foutmelding. Ongetwijfeld zal het een globale variabele zijn die elders gedefinieerd wordt; in dat geval zou het voldoende moeten zijn om
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?
global $dbconnection_N;
?>

aan het begin van show_permalink() op te nemen. Of je geeft $dbconnection_N mee als parameter aan show_permalink(); dat werkt ook als $dbconnection_N geen globale variabele is maar in de scope van een andere functie is gedefinieerd.

Ik neem aan dat je met "2 databases" bedoelt dat de databases zich op verschillende servers bevinden? Als je MySQL-server de federated engine ondersteunt, zou je ook nog kunnen werken met federated tables; op die manier kun je zelfs joins uitvoeren met tabellen die op een andere server staan. Maar let op, want er zitten wel wat haken en ogen aan qua query-optimalisatie.
Gewijzigd op 06/09/2024 02:05:05 door Willem vp
 
Mar kla

mar kla

06/09/2024 22:22:04
Quote Anchor link
Het zijn twee database die op één server draaien.

De databases heb ik gesplitst omdat de database met nieuwsberichten onder de "nieuws" website hangt en de wedstrijden database onder de "wedstrijden" website.

De enige link die er tussen beide databases is, is dat een nieuwsbericht mogelijk ook een wedstrijdverslag is dat bij en wedstrijd uit de wedstrijden database hoort.

In de index.php heb ik een
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
include_once $inc_directory. "inc-i-n-connect.php";
staan.

Daarmee lukt het me om binnen de nieuws website overal $dbconnection_N; gebruiken. dan is deze toch
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
Global [/code}


Maar de function show_permalink wordt aangeroepen vanuit de pagina die primair $dbconnection_N gebruikt.

Moet ik misschien ergens eerst een mysqli_close($conn);   doen??
 
- Ariën  -
Beheerder

- Ariën -

06/09/2024 22:32:05
Quote Anchor link
Infeite is het een kwestie van dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
/* Connectie gegevens hier */

$mysqli = new mysqli($host, $user, $password);

// Controleer de verbinding
if ($mysqli->connect_error) {
    die("Verbinding mislukt: " . $mysqli->connect_error);
}


// Selecteer de eerste database
$db_nieuws = "nieuws";
$mysqli->select_db($db_nieuws);

// Voer een query uit in de eerste database
$query1 = "SELECT * FROM table1";
$result1 = $mysqli->query($query1);
if ($result1) {
    while ($row = $result1->fetch_assoc()) {
        print_r($row);
    }
}


// Wissel naar de tweede database
$db_wedstrijden = "wedstrijden";
$mysqli->select_db($db_wedstrijden );

// Voer een query uit in de tweede database
$query2 = "SELECT * FROM table2";
$result2 = $mysqli->query($query2);
if ($result2) {
    while ($row = $result2->fetch_assoc()) {
        print_r($row);
    }
}


// Sluit de verbinding
$mysqli->close();
?>
 
Mar kla

mar kla

06/09/2024 22:36:11
Quote Anchor link
Dank voor de sneller reactie. ziet er overzichtelijk uit. ik ga er dit weekend even voor zitten.
 
Willem vp

Willem vp

06/09/2024 23:40:23
Quote Anchor link
Mar kla op 06/09/2024 22:22:04:
Het zijn twee database die op één server draaien.
Mooi, dat houdt het simpel.

Quote:
In de index.php heb ik een
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
include_once $inc_directory. "inc-i-n-connect.php";
staan.

Daarmee lukt het me om binnen de nieuws website overal $dbconnection_N; gebruiken. dan is deze toch Global
Ja, maar waarschijnlijk gebruik je verder geen functies waarin je $dbconnection_N nodig hebt, anders had je dit probleem al eerder gehad. Een functie erft (in PHP) niet standaard de globale variabelen uit de overkoepelende scope; dat moet je expliciet aangeven. Voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
$x
= 1;
function
echo_x ()
{

   echo $x;
}

echo_x();
?>

Dit zal geen output opleveren, maar
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
$x
= 1;
function
echo_x ()
{

   global $x;
   echo $x;
}

echo_x();
?>

doet wel wat je verwacht.

Tijdens mijn studie (alweer 35 jaar geleden; ik geloof dat ik oud begin te worden) werd ons expliciet verboden om globale variabelen te gebruiken; je zou bijvoorbeeld in een andere functie per ongeluk een variabele met dezelfde naam kunnen gebruiken en daarmee ongewild de waarde van de globale variabele veranderen. Dat zijn fouten waar je maanden naar kunt zoeken. PHP probeert je daartegen te beschermen door te vereisen dat je expliciet aangeeft dat je een variabele uit de globale scope wilt gebruiken.

Quote:
Maar de function
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
show_permalink
wordt aangeroepen vanuit de pagina die primair $dbconnection_N gebruikt.

Moet ik misschien ergens eerst een
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
mysqli_close($conn);
doen??

Nee, maar je moet wel aangeven op welke database/tabel je de query wilt uitvoeren. Dat kan op de manier die Ariën beschreef, met een select_db(), maar zelf vind ik het praktischer om dat in de query aan te geven. Dat wordt dan zoiets (voor de leesbaarheid laat ik even de foutafhandeling en zo weg):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$mysqli
= new mysqli($host, $user, $password);

$query1 = "SELECT * FROM nieuwsdb.newsitems";
$result1 = $mysqli->query($query1);
// Haal data op en doe er iets mee

$query2 = "SELECT * FROM wedstrijddb.wedstrijden";
$result2 = $mysqli->query($query2);
// Haal data op en doe er iets mee
?>

Dit kan nog wel mis gaan (ook bij de code van Ariën) als je voor de databases 'nieuwsdb' en 'wedstrijddb' verschillende database-users hebt die alleen hun eigen database kunnen zien; in dat geval zul je nog de relevante grants moeten uitdelen.

En nu kunnen we zelfs nog een stapje verder gaan door de nieuwsitems meteen in de wedstrijdquery te joinen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$query
= "
   SELECT w.*, n.permalink
   FROM wedstrijddb.wedstrijden w
   LEFT JOIN nieuwsdb.nieuwsitems n ON n.NewsItem_ID = w.nieuwsbericht_id AND n.NewsItem_Publist = 'Y'
"
;
?>

Scheelt weer een query op je database. ;-)
Gewijzigd op 06/09/2024 23:58:59 door Willem vp
 
Ad Fundum

Ad Fundum

07/09/2024 16:15:28
Quote Anchor link
Gebruik toch gewoon een database die meerdere schema's ondersteunt, zoals PostgreSQL.
In plaats daarvan een beetje prutsen in MySQL, het is maar waar je zin in hebt?
 
- Ariën  -
Beheerder

- Ariën -

07/09/2024 18:25:45
Quote Anchor link
Volgens mij zijn er (tot waarschijnlijk jouw grootste teleurstelling) weinig webhosters die PostgreSQL aanbieden in hun pakketten. Standaard zit het ook niet in DirectAdmin.

Maar ik wil zeker toegeven dat het beter en vooral logischer is dan MySQL en MariaDB. Jij bent niet de enige in ieder geval.
 
Mar kla

mar kla

07/09/2024 19:40:09
Quote Anchor link
@adfundum wat Ariën schrijft klopt ook voor mij. Ik heb alleen mysql ter beschikking.

Van Mysql overstappen op PostgreSQL heeft voor mij zoiets als je auto laten ombouwen van Benzine naar Diesel :-|


Maar met alle tips ben ik op de oplossing gekomen door aan
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
function show_permalink { global $dbconnection_N; }
toe te voegen.

Bijkomend probleem was dat andere functies ook gingen mekkeren :-)
Die ook allemaal tevreden gesteld met een Global


Allemaal dank voor de hulp!
Gewijzigd op 07/09/2024 19:40:58 door mar kla
 
Ad Fundum

Ad Fundum

08/09/2024 14:06:45
Quote Anchor link
Mar kla op 07/09/2024 19:40:09:
@adfundum wat Ariën schrijft klopt ook voor mij. Ik heb alleen mysql ter beschikking.

Van Mysql overstappen op PostgreSQL heeft voor mij zoiets als je auto laten ombouwen van Benzine naar Diesel :-|


Maar met alle tips ben ik op de oplossing gekomen door aan
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
function show_permalink { global $dbconnection_N; }
toe te voegen.

Bijkomend probleem was dat andere functies ook gingen mekkeren :-)
Die ook allemaal tevreden gesteld met een Global


Allemaal dank voor de hulp!

Een VPS is zo geregeld. Als je het wegstreept tegen een uurtarief dan zijn dat de kosten niet.

Het klopt wel dat het een hele toer kan zijn om een draaiende applicatie van MySQL over te zetten naar PostgreSQL. Dat is over het algemeen niet iets dat je kunt laten doen, maar wat je zelf moet doen. Gelukkig is ook daar is tooling voor. Als je database niet te complex is (een tabel of 20) dan kan je het ook met PHP omzetten van MySQL naar PostgreSQL.

PostgreSQL is inderdaad net als diesel; krachtig en schaalbaar. Je loopt nooit tegen beperkingen aan en alles wat je in MySQL/PHP zelf opnieuw zou moeten bouwen is daar al voor je geregeld en getest en gecertificeerd. Zoals meerdere database schema's.
Korter: PostgreSQL zou de standaard moeten zijn bij PHP in plaats van MySQL.

Wat globals betreft; je zou je code beter vorm kunnen geven. Globals zijn een anti-patroon in software ontwerp. Het werkt, maar je moet niet vragen hoe. Eén van de effecten is onoverzichtelijke code, wat je zelf beaamt doordat je zegt dat je verrast werd doordat er nog andere functies niet meer werkten. Als het goed is waarschuwt je IDE van te voren tegen eventuele foutmeldingen, en wordt aangegeven hoe je je code kunt verbeteren voordat je het ook maar hoeft te draaien.
Je hebt het dus uiteindelijk werkend gekregen. Dat had met minder moeite gekund. Voor de volgende keer.
 
Ivo P

Ivo P

09/09/2024 09:10:55
Quote Anchor link
Als beide databases op dezelfde db-server draaien, is het een mogelijkheid om de wedstrijd-site-database-user ook (lees)rechten te geven op de nieuws database.

Daarmee zou je maar 1 connectie nodig hebben. In de query kun je dan aangeven in welke database de betreffende tabel staat.

Dat staat hierboven een paar keer genoemd, maar naar mijn idee in wat bedekt termen / ondergesneeuwd in lange tekst.

--
Weet in elk geval dat 1 user rechten kan hebben op meerdere databases.
en ook dat een database door meerdere users benaderd mag worden (mits je "control" panel dat in laat richten)
 
Aad B

Aad B

09/09/2024 16:40:19
Quote Anchor link
Wat Ivo zegt klopt, maak een user aan die in beide databases rechten geeft. In feite zijn dat dus gewoon schema's in plaats van databases. Ad-Fundum weet kennelijk nog niet dat je echt niet hoeft over te gaan op postgres. MySQL en MariaDB onder steunen deze principes ook. Een user kan rechten hebben op meerdere schema's en om het duidelijk te houden kan je dat ook in je query's verwerken door de de databasenaam (eigenlijk de schemanaam) als qualifier te gebruiken. Zoals WillemVP beschrijft en dan samengevoegd in 1 query.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
SELECT wedstrijdA, newsitemX"
FROM wedstrijddb.wedstrijden, nieuwsdb.newsitems
WHERE wedstrijden.nieuwsbericht_id = newsitems.nieuwsbericht_id
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.