Serialize Unserialize
Ik wil van een gebruiker naar de dbase zijn ID invoeren uiteraard en daarna wil ik weten wat hij/zij mee neemt bv.
User_ID : naam, Objects: Schep, Schelp, Parasol, Bier, Zonnebril
Dus de dbase bevat deze velden:
ID: User_ID: Objects.
En alles wat de gebruiker meeneemt, moet dus in Objects.
Maar later moet ik dus ook die gegevens op kunnen vragen zonder scheidingsteken.
Hoe doe ik dat? Iemand een idee?
Gewijzigd op 01/04/2023 21:05:13 door - Ariën -
Je kan het prima genormaliseerd opslaan in de database.
ID: User_ID: Objects_1: Objects_2: Objects_3: etc... en ik heb bv 50 objects.
Dus dan krijg je een zeer lange MySql DBase. Juist wat ik niet wil
Daarom vroeg ik me af hoe Serialize / Unserialize toe te kunnen passen.
Met een lange database die verticaal is, is niks mis. Ik heb zelfs tabellen met 30 miljoen records. En dat gaat prima.
Met (un)serialize ben je ook al fout bezig.
Dus verdiep je in databasenormalisatie.
Ik zit te denken aan meerdere tabellen: Een objecten tabel, een koppeltabel met de ID's van gebruikers en Objecten, en de Gebruikerstabel.
Gewijzigd op 01/04/2023 19:13:12 door - Ariën -
Het gaat erom dat per gebruiker verschillende objects hebben.
Gaat niet om 1 gebruiker, maar om meerdere.
Dan zou ik iedere keer een nieuwe dbase per gebruiker moeten aanmaken, is ook niet te doen.
ID : User_ID : Objects :
===+=========+=================================+
1 | 1 | Shcep, Parasol, Zonnebril, Tent |
===+=========+=================================+
Maar jij wilt me dus dit laten doen :
ID : User_ID : Object_1 : Object_2 : Object_3 : Object_4 :
===+=========+==========+==========+==========+==========+
1 | 1 | Schep | Parasol | Zonnebril| Tent |
===+=========+==========+==========+==========+==========+
Maar ik praat over 50 objecten, dus ik wil dat in 1 field wegzetten en ook kunnen ophalen.
Dus hoe doe ik dat?
Ik denk dat Ariën het heel goed snapt, en dat jij het zelf niet goed leest of niet goed snapt.
>> Dan zou ik iedere keer een nieuwe dbase per gebruiker moeten aanmaken, is ook niet te doen.
Dit wordt nergens gezegd en zou inderdaad nergens op slaan.
Wacht even de uitleg van Ariën af, zodat je beter begrijpt wat hij bedoelt.
En ik heb duidelijk aangegeven dat je NOOIT horizontaal moet uitbreiden.
Je moet in een koppeltabel een objectID koppelen aan een UserID met een record/rij/row. Snap je?
Gewijzigd op 01/04/2023 21:20:52 door - Ariën -
ID : User_ID : Objects :
===+=========+=========+
1 | 1 |Schep |
===+=========+=========+
2 | 1 |Parasol |
===+=========+=========+
3 | 1 |Zonnebril|
===+=========+=========+
Etc.... En stel ik heb dan 50 gebruikers? Dan wordt het toch een zooi op een gegeven moment.
Waarom niet de Objects per gebruiker niet in 1 veld, zodat ik meerdere records op kan slaan?
Als ik met het voorbeeld verder ga, dat op eens ook een gebruiker 2 komt, dan weet je waarom ik het bedoel.
Een gebruiker kan bv meerdere objects hebben, stel dat er 1 is die alle 50 pakt, dan snap je wat ik bedoel.
Daarom dat ik vroeg of het niet beter is om de objects per gebruiker in 1 field op te slaan?
Zoals ik al zei heb je drie tabellen nodig met deze velden:
objecten
- ID
- naam
gebruikers
- ID
- gebruikersnaam
- wachtwoord (hashed)
- etc...
gebruikers_objecten
- GebruikersID
- ObjectID
Ik denk dat je wel snapt hoe je de tabellen objecten en gebruiker in kan vullen. :-)
En bij de tabel gebruikers_objecten vul je steeds per record het ID van de gebruiker in, en het ID van het object.
En zie hier: Een genormaliseerde en overzichtelijke tabel met onbeperkt aantal objecten die je per gebruiker kan opslaan.
Oh ja, maak je geen zorgen dat je straks misschien 100 records hebt, want daar zijn database voor gemaakt. Ook al heb je er 50 miljoen, dan is dit geen enkel probleem.
Gewijzigd op 01/04/2023 21:40:41 door - Ariën -
Een gebruiker krijgt een keuze formulier met alle objecten en die kan hij aanvinken welke hij/zij wilt.
dan slaat het formulier de records op.
Dus dan moet ik kijken hoe ik dan dat oplos.
Zoals objecten[] in je name-argument? Dan heb je in $_POST['objecten'] een array zitten die je met foreach(){} kan doorlopen, en met een INSERT-query kan opslaan.
https://www.phptutorial.net/ beter zijn.
Die legt het aardig goed uit. Hoewel PHP.net, W3Schools en Gewijzigd op 01/04/2023 21:56:51 door - Ariën -
anders kom ik hier weer terug ;)
Ik denk dat het nu wel gaat lukken :-)
Je geeft de objecten nu (net als de gebruikers) een unieke ID, maar hebben de objecten inderdaad ook een identiteit? Zijn het uniek identificeerbare objecten, zoals auto's met kentekens? Of wil je alleen maar vastleggen dat gebruiker x "een parasol" meeneemt?
Ward van der Put op 02/04/2023 15:08:08:
Je geeft de objecten nu (net als de gebruikers) een unieke ID, maar hebben de objecten inderdaad ook een identiteit? Zijn het uniek identificeerbare objecten, zoals auto's met kentekens? Of wil je alleen maar vastleggen dat gebruiker x "een parasol" meeneemt?
Juist, maar misschien ook meer natuurlijk.
Met andere woorden: Ga je die objecten ook nog onder verdelen in categorieën?
- Ariën - op 02/04/2023 18:39:45:
Met andere woorden: Ga je die objecten ook nog onder verdelen in categorieën?
Nee, dat niet
Met een JOIN in je query kan je de titels ophalen als je gebruikers_objecten aanroept.
Dus je hebt in je database:
- 1 tabel voor gebruikers. Elke rij heeft een eigen ID;
- 1 tabel voor objecten. Elk object heeft een naam en een eigen ID;
- 1 koppeltabel om te weten welk object bij welke gebruiker hoort.
De koppeltabel werkt als volgt. Komt een combinatie van user_id en object_id er in voor, dan is een object gekoppeld aan de gebruiker. En anders niet.
Je schrijft: "Waarom niet de Objects per gebruiker niet in 1 veld, zodat ik meerdere records op kan slaan?"
Dat is niet hoe relationele databases bedoeld zijn. Je moet denken in verzamelingen. Een database is heel erg snel in het ophalen van alle objecten van een gebruiker, wanneer de tabel slechts twee integer-kolommen heeft, en wanneer je het ID van de gebruiker hebt:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
SELECT
object.id AS object_id
object.naam AS object_naam,
gebruiker_id IS NOT NULL AS aangevinkt
FROM object
LEFT JOIN object_gebruiker
ON object_gebruiker.object_id = object.id
WHERE object_gebruiker.gebruiker_id = $1
ORDER BY object.naam
object.id AS object_id
object.naam AS object_naam,
gebruiker_id IS NOT NULL AS aangevinkt
FROM object
LEFT JOIN object_gebruiker
ON object_gebruiker.object_id = object.id
WHERE object_gebruiker.gebruiker_id = $1
ORDER BY object.naam
Hiermee krijg je in 1x alle objecten voor in het formulier, met de status of ze zijn aangevinkt.
Gebruik in het formulier:
<input name="object[object_id]" type="checkbox" checked> object_naam
Als de optie niet is aangevinkt laat je het HTML-attribuut 'checked' gewoon weg.
Je krijgt dan in PHP (met de standaardinstellingen) de formuliergegevens in de associatieve array $_POST['object'].
Om het formulier op te slaan:
- start je een database transactie;
- wis je alle rijen van de gebruiker in de tabel object_gebruiker;
- sla je alle combinaties op uit $_POST['object'], vanuit een foreach()-lus;
- commit je de database transactie.
Ik ga er gemakshalve vanuit dat je de gebruiker_id al weet, bijvoorbeeld omdat de gebruiker eerst moet inloggen. En dat de gebruiker_id is opgehaald uit de database en bewaard in $_SESSION.