databases koppelen en bericht markeren als gelezen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 10:37:02
Quote Anchor link
Ik maak een messageboard voor een groep vrijwilligers. Hierop kan men berichten plaatsen voor elkaar. Deze berichten kunnen per gebruiker gemarkeerd worden als gelezen. Onder ieder bericht komt een table met fotos van de leden. De URL van deze foto is opgeslagen in een tabel in een database. Als een gebruiker op zijn foto klikt, dan veranderd zijn foto in een andere foto, zodat hij weet dat hij dit bericht gelezen heeft. Deze functie werkt prima.

Maar, probleem is dat ik al die gebruikers nu handmatig moet invoeren. Dat betekent dat zodra er een nieuwe vrijwilliger bijkomt, ik een tabel voor hem moet aanmaken en de code moet aanpassen om hem toe te voegen onder een bericht.

Wat ik wil bereiken is dat nieuwe leden automatisch worden toegevoegd. Ik heb een tabel waar alle leden in staan, deze kan bewerkt en opgeroepen worden door een pagina. Ik wil dat, als ik op deze ledenpagina een gebruiker toevoeg, deze nieuwe persoon ook automatisch onder alle berichten wordt geplaatst. En zodra een vrijwilliger weggaat, hij niet meer gedisplayd wordt onder een bericht.

Als ik nu de gegevens van alle leden inlaad via een `mysql_fetch_array` functie direct onder ieder bericht, dan creëer ik geen unieke. Dat wil zeggen dat als persoon A bericht 1 wil afvinken, hij op alle geplaatste berichten afgevinkt wordt en niet alleen voor bericht 1. Ik wil dus dat ieder bericht een unieke table krijgt met alle leden erin (welke dus uit de database gehaald wordt), waarbij alleen dat bericht de gebruiker afgevinkt wordt.

Hoe doe ik dit?

Wat ik tot nu toe heb:

<b>De tabel db_users</b>
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
    id (AI), primary
    naam (varchar), 255
    adres (varchar), 255
    email (varchar), 255
    isActief (varchar), 5 //als deze `value` op ja staat, dan wordt zijn foto wel zichtbaar onder ieder bericht. Als deze `value` op nee staat dan wordt hij niet meer getoond.


<b>De tabel db_messages</b>
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
     id (AI), primary
     naam (varchar), 255 //de naam van de persoon die het bericht plaatst
     bericht (varchar), 999 //het bericht zelf
     urlUserA // De url van de foto van vrijwilliger A
     urlUserB // De url van de foto van vrijwilliger B
     urlUserC // De url van de foto van vrijwilliger C

<b>mark_read.php</b>
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
    $sql2 = "SELECT * FROM $tbl_name WHERE id = ".$_GET['id']; //om het specifieke bericht te krijgen
    $result2 = mysql_query($sql2);
    $url = $_GET['url']; // De url van de MARKEER-GELEZEN foto                
    $recover = $_GET['recover']; // De url van de MARKEER-ONGELEZEN foto        
    $tabel = $_GET['tabel'];
    $id = $_GET['id'];
    $date = $_GET['date'];
    $row = mysql_fetch_assoc($result2);            
    $tabel_content = $row[$tabel];

    if ($tabel_content == $url){
        $sql = "UPDATE " . mysql_real_escape_string($tbl_name) .
           " SET ".$_GET['tabel']." = '".$_GET['recover'].
           "' WHERE id = ".$_GET['id'];
      $result = mysql_query($sql);
    }
    elseif ($tabel_content == $recover) {
        $sql = "UPDATE " . mysql_real_escape_string($tbl_name) .
           " SET ".$_GET['tabel']." = '".$_GET['url'].
           "' WHERE id = ".$_GET['id'];
      $result = mysql_query($sql);
    }

Bovenstaande code is er om te kijken of een gebruiker het bericht al gelezen heeft of niet. Als hij gemarkeerd is wordt dit ongedaan gemaakt na klikken. Als dit bericht ongelezen is wordt hij gemarkeerd na klikken.

Zoals je kunt zien moet ik dus iedere keer een gebruiker toevoegen aan de code en aan de tabel, een hoop omslachtig werk. Ik wil dus dat als ik in `db_user` een gebruiker toevoeg, hij ook meteen zichtbaar is onder de berichten, zonder een nieuwe table `urlUserD` aan te hoeven maken.

Het bericht wordt geplaatst via deze pagina:

<b>addMSG.php</b>
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
    mysql_connect("$host", "$username", "$password")or die("cannot connect");
    mysql_select_db("$db_name")or die("cannot select DB");

    $onderwerp = $_POST['onderwerp'];
    $datum = $_POST['datum'];
    $bericht = $_POST['bericht'];
    $naam = $_POST['naam']; // de naam van de persoon die het bericht plaatst

    $sql="INSERT INTO $tbl_name(
    datum,
    archief,
    jaar,
    bericht,
    naam,
    onderwerp
    )
    VALUES(
    '$datum',
    'nee',
    '2014',
    '$bericht',
    '$naam',
    '$onderwerp'
    )";

    $result = mysql_query($sql);


Hoe (en waar) maak ik een code om alles aan elkaar te koppelen?
Gewijzigd op 14/05/2014 11:13:07 door Jeffrey van Zwam
 
PHP hulp

PHP hulp

17/11/2024 01:49:55
 
Michael -

Michael -

14/05/2014 10:39:21
Quote Anchor link
Gelieve code tussen [code] en [/code] tags plaatsen.
Rechts bovenin je bericht kun je deze wijzigen. Alvast bedankt.
Gewijzigd op 14/05/2014 10:39:42 door Michael -
 
Erwin H

Erwin H

14/05/2014 11:02:07
Quote Anchor link
Jeffrey van Zwam op 14/05/2014 10:37:02:
Maar, probleem is dat ik al die gebruikers nu handmatig moet invoeren. Dat betekent dat zodra er een nieuwe vrijwilliger bijkomt, ik een database voor hem moet aanmaken en de code moet aanpassen om hem toe te voegen onder een bericht.

Wat ik wil bereiken is dat nieuwe leden automatisch worden toegevoegd. Ik heb een database waar alle leden in staan, deze kan bewerkt en opgeroepen worden door een pagina. Ik wil dat, als ik op deze ledenpagina een gebruiker toevoeg, deze nieuwe persoon ook automatisch onder alle berichten wordt geplaatst. En zodra een vrijwilliger weggaat, hij niet meer gedisplayd wordt onder een bericht.

Ten eerste: weet waar je het over hebt. Overal waar je zegt 'database' hierboven bedoel je tabel. Per site werk je over het algemeen met 1 database, niet met meerdere. Laat staan dat je voor elke gebruiker een eigen database gaat aanmaken!

Tevens ga je ook niet voor elke nieuwe gebruiker een tabel aanmaken, hooguit een record in de users tabel. Vervolgens heb je en tabel met de berichten en die berichten moeten aan gebruikers worden gekoppeld. Dat is een zogenaamde many-to-many relatie. Elk bericht kan door meerdere gebruikers gelezen worden en elke gebruiker kan meerdere berichten lezen. Om deze relatie op te slaan maak je een koppeltabel aan in de database. Die koppeltabel koppelt de berichten aan de gebruiker. Elke keer dat een gebruiker een bericht leest, plaats je een nieuw record in die koppeltabel met het id van het bericht en het id van de gebruiker. Mocht een gebruiker het bericht weer willen terugzetten naar 'ongelezen' dan haal je dat record gewoon weer weg.
Als je dan voor een bepaald bericht wilt zien welke gebruiker het bericht hebben gelezen, dan kan je met een simpele query alle records voor dat bericht uit de koppeltabel ophalen.
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 11:11:04
Quote Anchor link
maar hoe kom ik aan die ID? Ik heb al iets gelezen over de mysql_insert_id() functie, maar krijg dit niet goed werkend
 
Erwin H

Erwin H

14/05/2014 11:12:51
Quote Anchor link
Hoe bedoel je 'hoe kom ik aan het id'?
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 11:14:30
Quote Anchor link
Erwin H op 14/05/2014 11:02:07:
Om deze relatie op te slaan maak je een koppeltabel aan in de database. Die koppeltabel koppelt de berichten aan de gebruiker. Elke keer dat een gebruiker een bericht leest, plaats je een nieuw record in die koppeltabel met het id van het bericht en het id van de gebruiker.


het id van het bericht & het id van de gebruiker bedoel ik
 
Erwin H

Erwin H

14/05/2014 11:16:57
Quote Anchor link
Het id van de gebruiker heb je als het goed is in een session staan (want je wil toch weten wie ingelogd is en iets doet), het id van het bericht heb je op het moment dat je de pagina aanmaakt om naar de browser te sturen. Dat staat waarschijnlijk in een $_GET variabele, en dat zeg je zelf al:
Quote:
$sql2 = "SELECT * FROM $tbl_name WHERE id = ".$_GET['id']; //om het specifieke bericht te krijgen
Gewijzigd op 14/05/2014 11:17:46 door Erwin H
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 11:21:12
Quote Anchor link
ik werk niet met sessions voor de gebruikers. Het is vrij toegankelijk, iedere gebruiker komt op dezelfde pagina uit.
 
Erwin H

Erwin H

14/05/2014 11:22:21
Quote Anchor link
Dan kan je nooit weten wie iets heeft gedaan en heeft deze hele functie geen zin. Op de een of andere manier moet je bijhouden wie de pagina bekijkt.
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 18:06:37
Quote Anchor link
Jawel, dat werkt nu ook. Iedereen kan van elkaar zien wie het bericht gelezen heeft. Als ik bijvoorbeeld op de pagina kom en ik lees bericht 1, dan klik ik op mijn foto onder bericht 1. De pagina markRead.php zorgt ervoor dat de src van de afbeelding veranderd. Deze wordt namelijk op deze manier gedisplayed:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<img src='user_".$value.".png' />


Ik kan hierdoor bijvoorbeeld ook op de foto's van andere gebruikers klikken zodat deze veranderen, maar dat is niet erg, dat mag juist.

Alle gebruikers staan in een tabel en hebben allen een uniek ID, alle berichten staan in een andere tabel en hebben ook allen een uniek ID, deze moeten op de een of andere manier aan elkaar gekoppeld worden.
 
Erwin H

Erwin H

14/05/2014 18:37:29
Quote Anchor link
Jeffrey van Zwam op 14/05/2014 18:06:37:
Ik kan hierdoor bijvoorbeeld ook op de foto's van andere gebruikers klikken zodat deze veranderen, maar dat is niet erg, dat mag juist.

Dus elke boerel*l kan op een foto klikken zodat die persoon opeens een bericht niet meer heeft gelezen, of juist wel. Nou, lekkere site dan....
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 18:52:26
Quote Anchor link
Daar zitten redenen achter. Ik waardeer je eerste poging tot helpen, maar ik ben op zoek naar een oplossing voor mijn vraag, niet naar de mening of hetgeen ik maak een "lekkere site" is.
 
Erwin H

Erwin H

14/05/2014 19:07:33
Quote Anchor link
Fair enough. Maar ik geef mijn mening omdat ik je probeer te helpen.... Volgens mij mag dat ook.

Anyway. Als je zegt dat er op een link geklikt moet worden, dan is het een peace of cake om in die link beide ids te verwerken. Het bericht id heb je uit de database waar je alle gegevens van de berichten uit haalt. En het gebruikers id heb je uit de database omdat je moet weten welke foto's je moet plaatsen. Beide verwerk je in de link en lees je uit op de pagina waar de link naar verwijst. De rest is dan niet zo moeilijk meer.
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 19:21:55
Quote Anchor link
Bedankt dat je toch doorgaat met helpen :)

Ik weet niet zo goed hoe ik dit duidelijk moet uitleggen. Bovenstaand klinkt inderdaad eenvoudig, maar dat is 'm niet. Onderaan ieder bericht moeten de gebruikers getoond worden. Dus voordat deze doorgegeven worden moet een code eerst kijken welke ID's er überhaupt in de tabel staan. Vervolgens moeten al deze ID's doorgegeven worden. En dat is precies wat ik niet voor elkaar krijg.

Want, even een voorbeeld, hoop dat ik het zo duidelijker kan maken:

Stel je voor. Dit is de pagina (vanaf de voorzijde, dus niet de codering), VW staat voor vrijwillger (hier staat normaal dan dus de foto van die persoon):

bericht 1
VW A | VW B | VW C

bericht 2
VW A | VW B | VW C

enz.

nu ben ik VW a en ga een nieuw bericht plaatsen, het 3e bericht in dit voorbeeld. Ik heb nu een pagina die het bericht in de database plaatst, maar vervolgens moet een andere code kijken welke VW er onder dit bericht geplaatst moeten worden, waardoor:

bericht 3
VW A | VW B | VW C

wordt bereikt.

Al deze vrijwilligers staan dus in een andere tabel.

Nu meldt zich een nieuwe vrijwilliger aan, in dit voorbeeld is hij dus VW D. Als ik hem toevoeg in de database moet hij meteen ook zichtbaar zijn, waardoor mijn pagina vanaf nu dus zo uitziet:

bericht 1
VW A | VW B | VW C | VW D

bericht 2
VW A | VW B | VW C | VW D

bericht 3
VW A | VW B | VW C | VW D

Snap je?

Nou, stel je voor dat VW C bij ons weggaat, dan haal ik hem uit de database. Vanaf dat moment moet de pagina dus zo uit komen te zien (zonder dat ik, behalve van het verwijderen uit de lijst, nog verdere aanpassingen hoef te doen):

bericht 1
VW A | VW B | VW D

bericht 2
VW A | VW B | VW D

bericht 3
VW A | VW B | VW D


Maar, tricky hierbij is, dat als ik op VW A onder bericht 1 klik, alleen deze waarde wordt veranderd (middels de update functie). Het moet dus niet zo zijn dat als ik op VW A onder bericht 1 klik, alle waardes van VW A worden veranderd (dus ook bij bericht 2 en 3). Alleen het bericht waar de persoon klikt, daarvan mag de waarde veranderd worden.

En dan komt de vraag: hoe?

Heb ik het zo duidelijk uitgelegd?
 
Erwin H

Erwin H

14/05/2014 19:37:47
Quote Anchor link
Ten eerste, onder elk bericht staan toch alle gebruikers (als ik het goed begrijp)? Dat is dan vrij eenvoudig om op te halen, namelijk gewoon selecteer all gebruikers uit de gebruikers tabel en met een for loop plaats je alle foto's.

Ten tweede, aan het begin staan alle gebruikers nog als niet gelezen, immers, niemand kan een bericht lezen als het nog niet bestaat. Alle foto's zijn dus niet aangevinkt, er hoeven nog geen records in die koppeltabel.

Als je nu de pagina opmaakt dan heb je dus alle berichten nodig. Die selecteer je uit de database, met id. Vervolgens moeten alle foto's eronder, die selecteer je aan de hand van de gebruikers uit de database, ook weer met id.
Dan loop je door de berichten heen en bij elk bericht loop je door de gebruikers heen en zo krijg je de ids bij elkaar. Die zet je in de link en klaar is klara. Schematisch:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$berichten
= array( ... );      //komt dus uit de database
$gebruikers = array( ... );     //komt ook uit de database

foreach( $berichten as $bericht ){
  echo $bericht['text'];
  foreach( $gebruikers as $gebruiker ){
    echo '<a href="markRead.php?bericht_id='.$bericht['id'].'&gebruiker_id='.$gebruiker['id'].'">foto</a>';
  }
}

?>


Toevoeging op 14/05/2014 19:40:16:

In markRead vervolgens lees je de beide id's uit de GET array en insert je die in de koppeltabel.

Daarna zal je alleen in bovenstaande methode een kleine aanpassing moeten maken. Want nu heb je wel een koppeling tussen gebruiker en bericht en zal je dus aan de hand van die koppeling een andere link moeten maken. Ofwel naar een andere pagina, ofwel naar dezelfde met een extra parameter. Is er namelijk al een koppeling, dan moet je niet nog een koppeling toevoegen na een klik, maar juist verwijderen.
 
Jeffrey van Zwam

Jeffrey van Zwam

14/05/2014 19:55:24
Quote Anchor link
okee, ik denk dat ik met bovenstaande wel aan de slag kan! maar je hebt het goed begrepen ;) Thanks! Ik meld me later wel met de uitslag!
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

14/05/2014 20:13:10
Quote Anchor link
Zoals eerder aangegeven kan je het beste een koppeltabel maken waarin je per gebruiker de gelezen berichten in opslaat:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
CREATE TABLE messages_read (
    user_id INT,
    message_id INT,
    PRIMARY KEY (user_id, message_id)
)

Nu moeten we ervoor zorgen dat alle berichten aan alle gebruikers gekoppeld worden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
SELECT DISTINCT
    user.id user_id
    messages.id message_id
FROM
    users
CROSS JOIN
    messages

Als we dit als subquery in een andere query gaan gebruiken kunnen we bepalen of het bericht wel of niet gelezen is:
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
SELECT
    um.user_id
    um.message_id
    IF(mr.user_id IS NULL, 0, 1) message_read
FROM
    (SELECT DISTINCT
        user.id user_id
        messages.id message_id
    FROM
        users
    CROSS JOIN
        messages
    ) um
LEFT JOIN
    messages_read mr
    ON um.user_id = mr.user_id AND um.message_id = mr.message_id

Aan jou om de te bedenken hoe daar de overige info bij te krijgen

Als je deze 3 gegevens in de link van de foto zet, kan je in mark_read.php aan de hand van message_read wel bepalen of je een record moet inserten danwel deleten uit messages_read.

Dit is het antwoord op je vraag.

Als je hier op dit forum een bericht plaatst, zullen er altijd mensen zijn die kritisch kijken naar hoe je met bepaalde dingen omgaat.
Dat is niet bedoeld om je te pesten, maar je te behoeden voor gevaren die je loopt als je niet nadenkt over beveiliging van je site.
Gewijzigd op 14/05/2014 21:19:01 door Ger van Steenderen
 



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.