PDA

Volledige versie bekijken : Gegevens uit database (MySQL) weergeven met php.


Emveedee
%Europe/Berlin %706 %2006, 17:57
Ik ben bezig met t leren van PHP icm MySQL.
Ik heb in mn database een tabel genaamd
proefwerken, met daarin 4 rijen genaamd
ll_id, naam, achternaam, email en cijfer.

Ik kan deze met een while loop weergeven.

Nu wil ik ook het hoogste, laagste en gemiddelde
punt laten zien, en t aantal leerlingen.

De sql die ik gebruik is

SELECT MAX(cijfer) FROM proefwerken;


En bij die andere dus COUNT, MIN en AVG.

Echter, als ik deze echo krijg ik ipv
T goede nummer 'Resource id #4' te zien
(en nummer 5,6,7)

Moet ik iedere keer als ik zoeits opvraag dat per sé
met n while loop doorlopen?
Of kan dat ook anders?

Mn code:

<?php

$title = "Verbinding maken met een database";

$server = bla;
$user = bla;
$pass = "bla";
$dbname = "bla";

$query = "SELECT * FROM proefwerken;";

if($db = mysql_connect($server, $user, $pass))
{
$message = "Connection to database <u>established</u> \n";

if(mysql_select_db($dbname, $db))
{
$message .= "and database $dbname has been selected <br>\n";

if($result = mysql_query($query, $db))
{
$message .= "and the query $query has been performed.\n";
}
else
{
$message .= "although the query $query could not be performed.\n";
}
}
else
{
$message .= "but opening database $dbname failed.\n";
}
}
else
{
$message = "Connection to database <u>failed</u>. \n";
}

include ('header.php');

echo $message;

echo "<hr>\n";

echo "<table width='610' border='1'>\n";
echo "<tr>\n";
echo "<td width='10'>id </td>\n";
echo "<td width='300'>Naam</td>\n";
echo "<td widht='250'>Email</td>\n";
echo "<td widht='50'>Punt</td>\n";
echo "</tr>\n";

while(list($id, $name, $last_name, $email, $mark) = mysql_fetch_row($result))
{
echo "<tr>\n";
echo "<td width='10'>$id</td>\n";
echo "<td width='300'>$name $last_name</td>\n";
echo "<td widht='250'><a href=\"mailto:$email\">$email</a></td>\n";
echo "<td widht='50'>";
if($mark < 5.5) echo "<font color='#FF0000'><b>";
echo $mark;
if($mark < 5.5) echo "</b></font>";
echo "</td>\n";
echo "</tr>\n";
}
echo "</table>\n";

$numberofids = mysql_query("SELECT COUNT(*) FROM proefwerken", $db);
$highest = mysql_query("SELECT MAX(cijfer) FROM proefwerken;", $db);
$lowest = mysql_query("SELECT MIN(cijfer) FROM proefwerken;", $db);
$average = mysql_query("SELECT AVG(cijfer) FROM proefwerken;", $db);
echo "Aantal punten: $numberofids <br>\n";
echo "Het hoogste punt: $highest <br>\n";
echo "Het laagste punt: $lowest <br>\n";
echo "Het gemiddelde: $average <br>\n";

include ('footer.php');

mysql_close($db);
?>

Alvast bedankt :)

PS: het resultaat kan je zien op
http://www.marc.stellan.nl/php/SQL/index.php

brossiekoppie
%Europe/Berlin %716 %2006, 18:11
Je moet er bvb nog een functie als mysql fetch assoc tussen steken.

Ten tweede kan het ook korter:

SELECT COUNT(*) as aantal, min(cijfer) as minimum, avg(cijfer) as gemiddelde FROM proefwerken;


$data = mysql_fetch_assoc($result);
foreach ($data as $key => $value) {
echo $key . ' is ' . $value;
}

Zou moeten werken denk ik

Emveedee
%Europe/Berlin %735 %2006, 18:38
Hmsh, zou je even willen uitleggen wat je precies doet?
php.net ziet er opeens heel erg f*cked up uit,
en is ook nog ns enorm traag (op 't moment).

brossiekoppie
%Europe/Berlin %383 %2006, 10:12
Dus je haalt gewoon het resultaat op met de query die ik gaf.

$query = 'SELECT COUNT(*) as aantal, min(cijfer) as minimum, avg(cijfer) as gemiddelde FROM proefwerken;';
$db = mysql_connect($server, $user, $pass);
mysql_select_db($dbname, $db);
$result = mysql_query($query, $db);
$data = mysql_fetch_assoc($result);
//hiermee haal je een associatieve array op van je opgehaalde gegevens
foreach ($data as $key => $value) { // één voor éé print je het resultaat
echo $key . ' is ' . $value;
}


Kijk eens of het werkt. Succes

josko
%Europe/Berlin %386 %2006, 10:16
Eemvedee, dit is een resultaat. namelijk de MAX().
Dit is nog eenvoudiger op te halen :) nl: mysql_result() (http://php.net/mysql_result)


<?php
$result = mysql_query( $sql );
$result = mysql_result( $sql, 0 ); //haal rij 1 van opgehaalde records op
?>

een idd, in mysql_fetch_.. functies kan het ook.

ik raad je aan gewoon even op php.net/mysql_query te kijken
ernaast zie je een rij met alle mysql functies :)

robert_m
%Europe/Berlin %563 %2006, 14:31
een idd, in mysql_fetch_.. functies kan het ook.
Je kan het beste mysql_fetch_assoc gebruiken veel sneller/beter en voor een array bestaan weer meer functies dan voor objecten (mysql_fetch_object). En als je een andere fetch functie gebruikt met een array krijg je een array terug waarbij de key's nummers zijn. Als je dan een kollom toevoegd moet je de hele query gaan aanpassen. Maar mysql_fetch_assoc heeft de kollomnaam als key's en is dus veel overzichtelijker.

josko
%Europe/Berlin %573 %2006, 14:46
mysql_fetch_array geeft ook associatieve array :)


Maar, krijgt hij meerdere rijen?
is het doel van een MAX opdracht meerdere rijen?
nee, 1 rij en 1 kolom.

Dus is het een beetje onzin om alle rijen te verwerken niet?

robert_m
%Europe/Berlin %575 %2006, 14:48
maar array haalt ze standaard beide op dus is ook een beetje overbodig.

En als maar een rij nodig is kan ook het beste aan de query LIMIT 1 worden toegevoegd want dan ontvang je allemaal de overrige rijen niet.

josko
%Europe/Berlin %585 %2006, 15:03
Euh? ooit een MAX(cijfer) gekregen van twee resultaten?:)




op msn erachter gekomen dat ik het over 1 max heb en hij over de gecombineerde sql van brossie.
andere woorden, je hoeft dit niet te lezen

robert_m
%Europe/Berlin %588 %2006, 15:07
Snap ik niet? :S Als je limit gebruikt leest hij wel gewoon alle rijen en pakt dus ook de max van alle rijen. (en max kan er natuurlijk maar een zijn)

Emveedee
%Europe/Berlin %698 %2006, 17:46
Hmm, raar..

Ik probeer een simpel blog-systeempje te schrijven.

Ik heb een database aangemaakt met erin 2 tabellen:
blogs en replies.

Blogs heeft de velden:
blog_id (dit is de primary key), author, time, date, text

Replies heeft de velden:
blog_id (primary key), time, date, author, text.

Ik probeer met dit script alles uit te lezen wat in de database staat,
echter hij geeft maar 1 rij terug: nl. de eerste rij van de tabel
die ik als laatste opgeef..

Wat doe ik fout?

<?php

$server = "localhost";
$user = "mvd_mvd";
$pass = "tafelpoot";
$dbname = "mvd_blog";

$db = mysql_connect($server, $user, $pass);
mysql_select_db($dbname, $db);

$query = "SELECT * FROM replies;";

$result = mysql_query($query, $db);

$data = mysql_fetch_assoc($result);

foreach($data as $key => $value)
{
echo "Key: $key; Value: $value<br>\n";
}

?>

Alvast bedankt :)

PS:

In mn db zitten 3 blogs,
en 2 replies (1 met blog_id 1, en 1 met blog_id 3);

robert_m
%Europe/Berlin %700 %2006, 17:49
Je moet nog een while lus gebruiken
<?php
while($data = mysql_fetch_array($result))
{
foreach($data as $key => $value)
{
echo "Key: $key; Value: $value<br>\n";
}
}
?>
En volgensmij doe je de datum en tijd verkeerd opslaan. Daarvoor kun je het beste het type DATETIME gebruiken en met een van de vele functies van MySQL om datums en tijden op te halen kun je hem splitsen in in nl formaat zetten.

Emveedee
%Europe/Berlin %702 %2006, 17:51
Thnx, zal eens kijken of dat werkt :)

Hoe bedoel je precies dat ik mn tijd/datum op moet slaan?

Gewoon als 1 kolom ipv 2?

Emveedee
%Europe/Berlin %705 %2006, 17:56
Hmm, die while lus laat wel meer resultaten zien,
maar t klopt nog niet helemaal:
Als ik gebruik
SELECT * FROM replies; of SELECT * FROM blogs; doet ie t goed,
echter wanneer ik doe:
SELECT * FROM blogs, replies;
gaat het fout..
Ik wil zien:
Blog 1, blog2, blog3, reply 1 , reply 2 (die volgorde is niet zo belangrijk),
maar ik zie:
reply 1, reply2, reply1, reply2, reply 1,
en wanneer ik blogs, replies verander in replies, blogs zie ik:
Blog1, blog2, blog3, blog1, blog2, blog3..

Wat doe k verkeerd?


<?php

$server = "localhost";
$user = "mvd_mvd";
$pass = "tafelpoot";
$dbname = "mvd_blog";

$db = mysql_connect($server, $user, $pass);
mysql_select_db($dbname, $db);

$query = "SELECT * FROM replies;";

$result = mysql_query($query, $db);

while($data = mysql_fetch_assoc($result))
{

foreach($data as $key => $value)
{
echo "Key: $key; Value: $value<br>\n";
}
}
?>

PS: mysql_fetch_array() verandert in mysql_fetch_assoc,
anders kreeg ik alle resultaten dubbel.

robert_m
%Europe/Berlin %710 %2006, 18:03
Je kunt denk ik het beste het eerst alle blogs ophalen. Dan de while lus beginnen iedere keer de bijbehorende reacties ophalen. Of je gaat eens spelen met een joins. Dat is wel meer programmeerwerk maar het script wordt denk ik wel sneller omdat je maar een query hebt. hier (http://www.phpfreakz.nl/artikelen.php?aid=45) nog een artikel over joins

Emveedee
%Europe/Berlin %716 %2006, 18:11
Hmm, mijn SQL-kennis begint langzaam terug te druppelen :P

Ik ga nog ff knutselen met inner joins,
kijken of ik er iets zinvols uit krijg.
(had toenstraks ook al wat geprobeerd
met inner joins, maar kreeg toen een mysql error)

Emveedee
%Europe/Berlin %725 %2006, 18:24
Nou, t is gelukt met inner joins :)

vreemd is wel dat t wel werkt met als query:

$query = "SELECT blogs.author as blogauthors, blogs.text as blogtexts, replies.author as replyauthors, replies.text as replytexts FROM blogs LEFT JOIN replies ON blogs.blog_id = replies.blog_id";
// en niet met
$query = "SELECT blogs.author, blogs.text, replies.author, replies.text FROM blogs LEFT JOIN replies ON blogs.blog_id = replies.blog_id";

Bedankt robert :)

robert_m
%Europe/Berlin %730 %2006, 18:31
Dat de ene wel werkt en de andere niet komt doordat je dan dubbele kollomnamen hebt. Maar met de query wat je nu hebt heb je wel alles onder elkaar staan met steeds post en reactie erbij volgensmij. Heb je dat al goed opgelost? (of je zou het zo moete wille)

Emveedee
%Europe/Berlin %767 %2006, 19:25
Nu krijg ik:

Blog1
Reply1
Blog2
Reply2 (leeg)
Blog3
Reply3

Dus op zich werkt t goed :)

Nu ff in een layout verwerken (ff wat aant prutsen met html en css).

Als k nog problemen tegenkom hoor je me wel :)

robert_m
%Europe/Berlin %390 %2006, 10:22
Maar volgensmij krijg je nu dit als je 2 of meer reacties hebt bij een blob
blog1
repley1
blog1
repley2
blog2
repley3
blog2
repley4
enz....

Dus dan moet je het huidige blog id in een var zetten. En dan controleren of het id uit de db gelijk is aan die var. Zo ja blog niet weergeven. Zo nee blog wel weergeven en var overschrijven met de nieuwe.

Emveedee
%Europe/Berlin %468 %2006, 12:14
Ik zal 't eens proberen.

Uiteindelijk zal ik toch of
alleen alle blogs laten zien,
of één blog met zn replies.

josko
%Europe/Berlin %480 %2006, 12:31
normaal zou je :
blog selectie

while( ->verwerking )
selecteer replys
geef bog weer
geef replies weer

robert_m
%Europe/Berlin %481 %2006, 12:32
@Josko
Maar dan moet je wel weer meer query's uitvoeren. Om steeds bij elk blog de repley op te halen. En als je joins gebruikt heb je maar een query nodig.

josko
%Europe/Berlin %502 %2006, 13:03
Ach, en met een join.

Voeg een variable toe:
$blogWeergegeven = array();
while()
{
if( $blogWeergegeven[ $mysql['id'] != true )
//glog weergeve+ var naar true zetten
}

Emveedee
%Europe/Berlin %631 %2006, 16:09
Oke, ik heb weer wat zitten prutsen,
maar k kom niet meer verder.

Ik heb 2 functies gemaakt, showBlog en
showReplies. (hun bedoeling zal wel duidelijk zijn :P )
Echter,
als ik showBlog uitvoer, zie ik de eerste reply niet..

Wat doe ik fout?


<?php

$server = "bla";
$user = "bla";
$pass = "bla";
$dbname = "bla";

if(!$_GET['blog'])
{
$currentblog = 1;
}
else
{
$currentblog = $_GET['blog'];
}


$query = "SELECT blogs.text as blogtexts, blogs.author as blogauthors, replies.text as replytexts, replies.author as replyauthors FROM blogs LEFT JOIN replies ON blogs.blog_id = replies.blog_id WHERE blogs.blog_id = $currentblog;";


$db = mysql_connect($server, $user, $pass) or die("Kon geen verbinding maken met de databaseserver");
mysql_select_db($dbname, $db) or die("Kon server " . $dbname . " niet kiezen");
$result = mysql_query($query, $db) or die("Kon de query " . $query . " niet uitvoeren");
mysql_close($db);


$css = "style.css";
$title = "Welkom op Marc's web-log :)";

include("header.php");

echo "<div id='holder'>\n\n<div id='menu'>\n<ul>\n<li> Blog 1 </li>\n<li> Blog 2 </li>\n<li> Blog 3 </li>\n</ul>\n</div>\n<div id='blogcontent'>\n";

showBlog($result);
showReplies($result);

echo "</div>\n</div>\n"; //closing blogcontent and holder
include("footer.php");


function showBlog($res)
{
$data = mysql_fetch_assoc($res);
echo "<div id='blog'>\n";
echo "<div id='content'>" . $data['blogtexts'] . "</div>\n";
echo "<div id='info'> " . $data['blogauthors'] . "</div>\n";
echo "</div>\n";
}

function showReplies($res)
{
while($data = mysql_fetch_assoc($res))
{
echo "<div id='reply'>\n";
echo "<div id='content'>" . $data['replytexts'] . "</div>\n";
echo "<div id='info'> " . $data['replyauthors'] . "</div>\n";
echo "</div>\n";
}
}
?>

Ik had ook al geprobeerd om aan t eind van showBlog()
reset($data) te doen, maar dat had geen effect..?

Alvast bedankt :)

josko
%Europe/Berlin %633 %2006, 16:11
Omdat de eerste rij van de resultset al verwerkt is.

Zoals gezegd, gebruik gewoon 1 while lus.

indien er al een keertje blog is weergegeven, echo je die niet meer.

Emveedee
%Europe/Berlin %646 %2006, 16:31
Hmm tis me gelukt met 1 while loop.


function showBlog($res)
{
$shownBlog = false;
while($data = mysql_fetch_assoc($res))
{
$nrOfReplies = $data['nrOfReplies'];
if($shownBlog == false)
{
echo "<div id='blog'>\n";
echo "<div id='content'>" . $data['blogtexts'] . "</div>\n";
echo "<div id='info'>Gepost door:" . $data['blogauthors'] . " Aantal Reacties: $nrOfReplies</div>\n";
echo "</div>\n";
$shownBlog = true;
}
if($data['replytexts'])
{
echo "<div id='reply'>\n";
echo "<div id='content'>" . $data['replytexts'] . "</div>\n";
echo "<div id='info'> " . $data['replyauthors'] . "</div>\n";
echo "</div>\n";
}
}
}

Nu wil ik nog 1 ding opvragen, nl. hoeveel replies er zijn.

Dit probeer ik dus door ipv

$query = "SELECT blogs.text as blogtexts, blogs.author as blogauthors, replies.text as replytexts, replies.author as replyauthors FROM blogs LEFT JOIN replies ON blogs.blog_id = replies.blog_id WHERE blogs.blog_id = $currentblog;";

Deze query te gebruiken:

$query = "SELECT COUNT(replies) as nrofreplies, blogs.text as blogtexts, blogs.author as blogauthors, replies.text as replytexts, replies.author as replyauthors FROM blogs LEFT JOIN replies ON blogs.blog_id = replies.blog_id WHERE blogs.blog_id = $currentblog;";

Maar dan krijg ik een error..?

josko
%Europe/Berlin %648 %2006, 16:34
<?php
$query = "SELECT COUNT(*) replies WHERE blog_id ='".$currentblog."'";
?>
denk dat het zo beter is :)

Emveedee
%Europe/Berlin %654 %2006, 16:42
Dan moet ik 2 querys uitvoeren, en dat wil ik niet.

Overigens (heb t niet geprobeerd) gaat jouw
query zo te zien sowieso een error geven,
je geeft geen FROM op (of die ben je vergeten.)

josko
%Europe/Berlin %664 %2006, 16:56
<?php
$query = "SELECT COUNT(*) FROM replies WHERE blog_id ='".$currentblog."'";
?>
uhmz...
ff kijken of dit mag :)

SELECT COUNT( _one.* ) as countOne,
COUNT( _two.* ) as countTwo,
COUNT( _three.* ) as countThree
FROM replies as _one, replies as _two, replies as three,
WHERE _one.id = '1' AND _two.id = '2' AND _three.id = '3'


zoiets :p

vraag twee is dan of ie niet gaat zeuren

Emveedee
%Europe/Berlin %671 %2006, 17:06
Ik gebruik nu toch twee queries,
1 voor het opvragen van de blog,
en 1 voor het opvragen van de replies.

Dit vind ik fijner omdat ik dan de showBlog
en showReply functie apart kan houden :)

robert_m
%Europe/Berlin %683 %2006, 17:23
Probeer dit eens
<?php
$result = mysql_query($query);
while($row = mysql_fetch_assoc($result))
{
if((!isset($blogid)) || ($blogid != $row['blogid']))
{
$blogid = $row['blogid'];
//geef het blog weer
}
//geef de repleys weer
}
?>
Je moet nu alleen in de query ook nog het id van het blog ophalen met als alias blogid

Edit:
is een beetje achterhaald maar mijn eerste nieuwe post stond onderaan de vorige pagina dus dacht dat er niks meer was

BernardV
%Europe/Berlin %963 %2006, 00:07
Wat hierboven eens genoemd is over een join met reacties.. dat zou ik niet doen.
Ik zou voor de extra query gaan.
Alleen al omdat als je een join gebruikt, je dus ook bij elke reactie de volledige post krijgt in het record. Er moet dus veel meer data van mysql naar php gestuurd worden en ik denk dat dat meer tijd kost dan die extra queries waarmee je gelijk de goede gegevens voor de replies kunt opvragen.

//EDIT:

Ook omdat je waarschijnlijk op een main page niet alle reacties gaat weergeven en misschien zelfs op een vervolgpagina niet eens alle reacties, maar dan in pagina's omdat het er veel worden.

Ik zou voor een class/functie gaan die je aanroept met een blogid en die geeft dan de reacties terug... Zo hou je het ook overzichtelijker wil je het straks weer eens hergebruiken in een andere layout.