MySql query binnen functie werkt niet, zelfde query er buiten wel

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Bas Prins

Bas Prins

19/04/2020 16:30:47
Quote Anchor link
Hallo,

Ik heb beperkt ervaring met PHP/MySQL, maar heb er wel een volledige website mee gebouwd (bpsdg.nl). Ik ben aan het experimenteren hoe ik een bepaalde pagina meer dynamisch kan maken. Onderstaande code is gebaseerd op iets dergelijks wat ik wil bereiken. Dus met name de function "printree" heb ik niet zelf bedacht, maar ergens opgepikt en wat aangepast. Code ziet er misschien nog wat rommelig uit, maar het is ook nog maar een experiment.

De function faalt op de regel "$rstpersonen = mysql_query($query_rstpersonen, $gen_db) or die(mysql_error());".
Als ik exact dezelfde 3 regels na "if ($N < $max) {" bovenaan direct achter "mysql_select_db($database_gen_db, $gen_db);" plaats, dan wordt op dat moment de query wel goed uitgevoerd. Maar het is dus de bedoelng dat de query recursief in de function meerdere keren wordt uitgevoerd. Maar faalt al bij de eerste keer.

Ik ben er al dagen mee bezig en zie gewoon niet wat ik fout doe. Iemand een idee?

Quote:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php
require_once('Connections/gen_db.php');
$colname_rstPersoonGegevens = "51"; //Default
if (isset($_GET['pID'])) {
  $colname_rstPersoonGegevens = (get_magic_quotes_gpc()) ? $_GET['pID'] : addslashes($_GET['pID']);
}

mysql_select_db($database_gen_db, $gen_db);


function
printTree($id, $name, $N, $max) {
         ##########################################
         # recursive routine to print cells in
         # pedigree chart
         #
         # Parameters
         #    - id
         #    - name
         #    - generation number
         #    - max previous generations to display
         ##########################################


         if ($name == '') $name = ' ';

         // calculate how many rows the cell should span

         $rspan = pow(2, $max-$N);

         if ($rspan > 1)
             echo "\t<td height='40' rowspan='$rspan' >$name</td>\n";
         else
             echo "\t<td>$name</td>\n";

         // check for last cell in row
         if ($N == $max) echo "</tr>\n<tr>\n";

         // print parent trees, sire then dam
         if ($N < $max) {
             $query_rstpersonen = "SELECT Vaders.Id as Vader, Moeders.Id as Moeder, Vaders.Voornaam as VaderNaam, Moeders.Voornaam as MoederNaam FROM tblPersonen Inner Join tblPersonen as Vaders ON Vaders.Id = tblPersonen.Vader Inner Join tblPersonen as Moeders  ON Moeders.Id = tblPersonen.Moeder WHERE tblPersonen.Id = ".$id;
             $rstpersonen = mysql_query($query_rstpersonen, $gen_db) or die(mysql_error());
             $row_rstpersonen = mysql_fetch_assoc($rstpersonen);
             list($s, $d, $sn, $dn) = $row_rstpersonen;
             printTree($s, $sn, $N+1, $max);
             printTree($d, $dn, $N+1, $max);
          }
}

function
pedigree($id, $name) {
    
    $max = 6;
    echo "<TABLE border='1'>\n";
    echo "<tr>\n";

    $i=1;  
    while($i<($max+1))  
    {

    echo "<th width='160'>".$i."</th>\n";
    $i++;  
    }

    echo "</tr>\n<tr>\n";

    printTree($id, $name, 0, $max-1);

    echo "<td colspan='5'>Produced by Barand</td></tr>\n</TABLE>\n";

}


?>

<HTML>
<head>
<title>Kwartierstaat</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_goToURL() { //v3.0
var i, args=MM_goToURL.arguments; document.MM_returnValue = false;
for (i=0; i<(args.length-1); i+=2) eval(args+".location='"+args[i+1]+"'");
}
//-->
</script>
<link href="stijlen.css" rel="stylesheet" type="text/css">
<link href="tootltip.css" rel="stylesheet" type="text/css">
<style type="text/css">
<!--
.style12 {font-size: 12px}
-->
</style>
</head>
<BODY>

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
  
     pedigree($colname_rstPersoonGegevens,'Melody');

?>

</BODY>
</HTML>[/quote]
 
PHP hulp

PHP hulp

25/04/2024 02:00:25
 
Thomas van den Heuvel

Thomas van den Heuvel

19/04/2020 16:38:09
Quote Anchor link
Als ik get_magic_quotes() zie, addslashes als "beveiliging" en mysql_* functies rijst bij mij de vraag: hoe oud is dit spul?

Waarom heb je een Connections/gen_db.php include, en maak je vervolgens daarbuiten een database-connectie?

Heb het bovenstaande bericht enkel geskimd, maar de reden dat queries ed niet werken binnen de functie is hoogstwaarschijnlijk omdat $gen_db hier binnen niet bekend is. Functies hebben een aparte scope voor variabelen. $gen_db valt daar niet onder.

Dat gezegd hebbende zou ik je aanraden je te verdiepen in modernere manieren om te communiceren met je database (mysqli of PDO) en ook hoe je hier met een veilige manier mee omgaat. addslashes() is eigenlijk nooit een goed middel geweest om queries te beveiligen.
 
- Ariën  -
Beheerder

- Ariën -

19/04/2020 16:43:16
Quote Anchor link
de mysql_***() functies zijn overigens sinds PHP 7.0 ter ziele gegaan. Als ze nu nog werken op de webserver heb je mazzel, maar er komt een moment aan dat je hele site 'breekt'. Dus stap liever over op de functies van mysqli_***() of die van PDO, hoewel die inbouw van PDO wat ingrijpender is.

Daarnaast wil je vragen om je code tussen code-tags te plaatsen. Dan is het beter leesbaar in een lijn-genummerd codeblok. Quoten is puur bedoeld voor citeren van tekst.
Gewijzigd op 19/04/2020 16:45:25 door - Ariën -
 
Frank Nietbelangrijk

Frank Nietbelangrijk

19/04/2020 16:50:30
Quote Anchor link
Oud schroot is dit. Om te beginnen zet voor het testen ALLE php foutmeldingen aan. Vervolgens moeten alle Mysql_ functies omgezet gaan worden in PDO of in mysqli_ maar dan wel met de mysqli error reporting aan anders blijf je nog zwemmen als je niet bij iedere mysqli_ functie niet heel goed de fouten gaat afvangen.

Iets anders dat zeer amateuristisch is in bovenstaand script is het gebruik van echo's binnen in de functies.

Functies zijn er voor gemaakt dat je ze informatie geeft waar ze iets mee doen en het resultaat daarvan wordt terug gegeven. Iets als:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
function optellen($a, $b) {
    return $a + $b;
}


echo optellen(2, 5);
?>


Zoals je ziet houden we de echo buiten de functie.
 
Bas Prins

Bas Prins

19/04/2020 18:00:51
Quote Anchor link
Maar, ik ben ook een amateur! Redelijk wat ervaring met programmeren, maar niet zoveel met PHP. De website is voornamelijk in 2007 gemaakt vooral met automatische code vanuit Dreamweaver. Dreamweaver heb ik niet meer, ik schrijf nu alleen code.

Het aantal echo's is afhankelijk van het aantal recursies van de functie, dus ik zie niet hoe ik de echo's buiten de functie kan brengen. Zal mogelijk ook aan mij liggen.

Ik besef dat ik de website moet upgraden naar de laatste PHP versie. Dat ben ik aan het bestuderen, maar de leercurve is vrij stijl.

Maar dankzij de opmerking van Thomas kwam ik op het idee om $gen_db gewoon in de parameters van de function te zetten. Zal ook wel geen schoonheidsprijs verdienen, maar samen met nog een paar aanpassingen doet het nu ik wil.
Ik dacht ook nog aan een global variabele voor de database (hetgeen ik meer gewend ben uit VB.net), maar ook dat lukte niet.

Allen bedankt voor de reacties.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

19/04/2020 18:29:45
Quote Anchor link
>> Het aantal echo's is afhankelijk van het aantal recursies van de functie, dus ik zie niet hoe ik de echo's buiten de functie kan brengen. Zal mogelijk ook aan mij liggen.

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
<?php
function printTree($id, $name, $N, $max)
{

    $html = '';
    
    if ($name == '') {
        $name = ' ';
    }

    
    // calculate how many rows the cell should span

    $rspan = pow(2, $max - $N);

    if ($rspan > 1)
        $html .= "\t<td height='40' rowspan='$rspan' >$name</td>\n";
    else
        $html .= "\t<td>$name</td>\n";

    // check for last cell in row
    if ($N == $max)
        $html .= "</tr>\n<tr>\n";

    // print parent trees, sire then dam
    if ($N < $max) {
        $query_rstpersonen = "SELECT Vaders.Id as Vader, Moeders.Id as Moeder, Vaders.Voornaam as VaderNaam, Moeders.Voornaam as MoederNaam FROM tblPersonen Inner Join tblPersonen as Vaders ON Vaders.Id = tblPersonen.Vader Inner Join tblPersonen as Moeders  ON Moeders.Id = tblPersonen.Moeder WHERE tblPersonen.Id = " . $id;
        $rstpersonen = mysql_query($query_rstpersonen, $gen_db) or die(mysql_error());
        $row_rstpersonen = mysql_fetch_assoc($rstpersonen);
        list($s, $d, $sn, $dn) = $row_rstpersonen;
        $html .= printTree($s, $sn, $N + 1, $max);
        $html .= printTree($d, $dn, $N + 1, $max);
    }

    
    return $html;
}

?>
Gewijzigd op 19/04/2020 18:30:53 door Frank Nietbelangrijk
 
- Ariën  -
Beheerder

- Ariën -

19/04/2020 18:30:40
Quote Anchor link
Je hebt twee mogelijkheden:
- De oude manier van het gebruik met functies aanhouden. Dan is het het een kwestie door een 'i' toe te voegen, en de documentatie van mysqli te lezen, omdat je meestal wat extra parameters toevoegen.

Dit zijn de voornaamste wijzigingen:

mysql_connect('localhost','user', 'password') => mysqli_connect('localhost','user', 'password','databasenaam')
mysql_select_db('databasenaam') => Zit nu in de mysqli_connect()
mysql_query(.....) => mysqli_query($connection, .........)
mysql_fetch_assoc(...) => mysqli_fetch_assoc(...)
mysql_num_rows() => mysqli_num_rows()
mysql_real_escape_string() => mysqli_real_escape_string($connectie,...)
mysql_error() => mysqli_error($connectie,...)

Of je gebruikt de object-georiënteerde methode:
https://www.w3schools.com/php/php_mysql_connect.asp

Die laatste werkt als een standaard class, die je makkelijk kan uitbreiden (extend) met een eigen class. Zo kan je bijvoorbeeld je queries tellen, of een overkoepelende foutafhandeling maken, of hulpfuncties maken om alles makkelijker te maken.
Gewijzigd op 19/04/2020 18:32:27 door - Ariën -
 
Frank Nietbelangrijk

Frank Nietbelangrijk

19/04/2020 18:39:46
Quote Anchor link
Valt me nu ook dat je een SELECT query hebt in een recursive functie. Dat zal waarschijnlijk erg traag zijn. De query zou buiten die functie moeten en in één keer alle benodigde records moeten ophalen.
Gewijzigd op 19/04/2020 18:46:47 door Frank Nietbelangrijk
 
Adoptive Solution

Adoptive Solution

19/04/2020 18:47:03
Quote Anchor link
Voor de liefhebber.

Hier de uitleg over hoe je de stamboom moet opvragen.

Het gaat weliswaar over paarden, maar je kan het ook op mensen toepassen.

forums.phpfreaks.com/topic/309519-display-pedigree-table-fron-mysql-with-php-by-levels/?do=findComment&comment=1571535

Volgens eigen zeggen is de code 15 jaar oud.

Ik heb het idee dat deze pagina overeenkomt met wat in dat forum wordt getoond.

www.bpsdg.nl/kwartierstaat.php?pID=833


Toevoeging op 19/04/2020 18:55:48:

Hier het origineel uit 2007

https://forums.phpfreaks.com/topic/64349-solved-why-doesnt-this-pedigree-work/?do=findComment&comment=321016
 
Bas Prins

Bas Prins

19/04/2020 19:58:29
Quote Anchor link
Die onderste link en dan die eerste post van meneer Barand is precies wat ik heb gebruikt.
 
Adoptive Solution

Adoptive Solution

19/04/2020 22:29:35
Quote Anchor link
Ik heb een database aangemaakt met de hondengegevens.

Om die te benaderen gebruik ik mysqli.

De verbinding maken gaat zo

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$db = new mysqli( 'localhost', 'gebruiker', 'wachtwoord', 'database' );


Om in de functie printTree() de database te benaderen, zet dit op de eerste regel binnen die functie :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
global $db;


Dan deze regel :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$res = mysql_query($sql);


veranderen in :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$res = $db->query( $sql )


En deze regel :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
list($s, $d, $sn, $dn) = mysql_fetch_row($res);


veranderen in :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
list( $s, $d, $sn, $dn ) = $res->fetch_row();


Dan moet het werken.

De rest aanpassen naar smaak.
 



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.