Noob vraag over instancieren van objecten
---------
require '/Controller/class_User.php'
$User = new User();
---------
En ik herlaad de index pagina, lijkt het erop dat het object iedere keer opnieuw wordt aangemaakt. Ik kan het mis hebben, maar ik kan het zo 123 niet op Google vinden.
Hoe instancieer ik een object, maar dan maar 1 keer ? Dus dat het zelfde object per bezoeker gebruitk wordt? Nu heb ik bij een page refresh dat het object dus opnieuw wordt aangemaakt, als ik dan 'echo $User->getName();' doe, is deze leeg.
Sorry voor de lastige uitleg, ik ben heel hard op weg om PHP en OOP te leren.
Toevoeging op 01/07/2014 12:29:33:
Doe ik dit met een meet if statement ? Dus checken met een if of $User al bestaat ?
Als je objecten langer houdbaar wilt maken, kun je ze opslaan in een PHP-sessie of een database door ze te serialiseren.
Maar neem het voorbeeld van de $User. Ik lees dat je zo min mogelijk in de sessie scope moet zetten en dat je voor alles wat je van de user wilt hebben gewoon een db query moet uitvoeren, maar hoe hou ik dan bij met welke user ik te maken heb? Zet ik dan minimaal een UserID in de sessie scope en haal ik dan iedere keer alle gegevens van de user uit de db, waarmee ik dan de class weer van data voorzie ?
In dat geval moet ik dus iedere keer als ik een naam van een gebruiker wil tonen, het eerst ophalen uit een db table, daarna met een setter de naam zetten en dan met een getter de naam outputten ?
De simpele oplossing is alleen de UserID opslaan in de sessie en daarmee bij elk request via een uitstapje naar de database een new User() genereren.
De minder simpele oplossing is de sessie gebruiken als cache en daarin het complete User-object opslaan.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Sessie starten of hervatten
session_start();
// Bevat de sessie een user?
if (isset($_SESSION['user'])) {
// Ja, user hergebruiken
$user = unserialize($_SESSION['user']);
} else {
// Nee, nieuwe user instantiëren ...
$user = new User();
// ... en die user later opslaan in de sessie
$_SESSION['user'] = serialize($user);
}
?>
// Sessie starten of hervatten
session_start();
// Bevat de sessie een user?
if (isset($_SESSION['user'])) {
// Ja, user hergebruiken
$user = unserialize($_SESSION['user']);
} else {
// Nee, nieuwe user instantiëren ...
$user = new User();
// ... en die user later opslaan in de sessie
$_SESSION['user'] = serialize($user);
}
?>
>> Ik lees dat je zo min mogelijk in de sessie scope moet zetten en dat je voor alles wat je van de user wilt hebben gewoon een db query moet uitvoeren, maar hoe hou ik dan bij met welke user ik te maken heb?
Dat is een keuze: het hangt er maar van af. Een van de eerste bottlenecks bij een groeiende site is het overschrijden van het maximumaantal databaseconnecties. Daarom is alles dat langer dan één request meegaat cachen een best practice in performance.
Je gaat bijvoorbeeld niet voor 10 pageviews 10 keer de voornaam van de gebruiker uit de database hengelen: die sla je op in de sessie.
Een tussenvorm is daarvoor dan ook nog mogelijk: niet het complete User-object cachen, maar alleen de voornaam.
Ik denk zelf dat ik het opslaan van het object in de sessie scope het meest netjes vind. Dat ga ik nu eerst proberen te fixen.
Thnx !
Toevoeging op 01/07/2014 14:50:43:
Is het dan zo dat als ik een naam gezet heb met een setter, dat die naam dan niet in de sessie scope mee komt ? Want ik kan nu idd het object uit de sessie halen, maar het lijkt erop alsof de data die ik aan de class geef verdwijnt na een page refresh..
of doe ik dan toch iets fout ?
Je moet het object pas serialiseren en opslaan in de sessie als het niet meer wijzigt, dus nádat de naam is ingesteld. Met serialize() maak je namelijk simpelweg een string-representatie van het object. Verandert het object daarna nog, dan zie je dat niet terug in die string-kopie.
-----------------------------
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
require_once '/Controller/class_UserController.php';
session_start();
if (isset($_SESSION['userController']))
{
$UserController = unserialize($_SESSION['userController']);
}
else
{
$UserController = new User();
$_SESSION['userController'] = serialize($UserController);
}
?>
require_once '/Controller/class_UserController.php';
session_start();
if (isset($_SESSION['userController']))
{
$UserController = unserialize($_SESSION['userController']);
}
else
{
$UserController = new User();
$_SESSION['userController'] = serialize($UserController);
}
?>
-----------------------------
Vervolgens heb ik in een andere file (login controller) het volgende staan:
-----------------------------
(eerst wordt er gekeken of het email adres van de user bestaat (wordt dan in $userFound(array) gezet), daarna check ik of het wachtwoord correct is. Daar komt dan in $check of true of false in te staan)
if ($check == true)
{
$_SESSION['loggedin'] = "true";
$UserController->setName($userFound[0][1]);
}
-----------------------------
Als ik op dit punt nu echo $UserController->getName(); doe, dan krijg ik netjes de naam terug die gezet is. Klik ik nu op een menu item om naar een andere pagina te gaan en ik ga weer terug naar de pagina waar ik de echo deed van de naam, dan zit er ineens geen waarde meer in.
Toevoeging op 01/07/2014 15:11:45:
"dus nádat de naam is ingesteld"
ok, dus ik moet het object opnieuw in de sessie scopre storen als ik setName het aangeroepen ???
Dan moet je inderdaad de volgorde veranderen: sla de $UserController pas op in de sessie wanneer de toestand ervan niet meer verandert. Met serialize() maak je slechts een kopie van het object, maar dan in de vorm van een string. Die kopie moet je dus pas opslaan als het origineel niet meer wijzigt, anders verschillen ze van elkaar.
Je geeft aan dat er een kopie wordt gemaakt, wat gebeurt er dan met het orgineel ? Want in principe heb je die nu niet meer nodig, kan die dan op de een of andere manier verwijderd worden ?
Of doe ik nu domme dingen door het object in deze check weer te serializeren ?
unset() gebruiken.
Praktisch voordeel daarvan is in dit geval vooral dat je fouten uitsluit: omdat al een kopie is opgeslagen in de (sessie)cache, voorkom je onopgemerkte wijzigingen als je het origineel resoluut verwijdert.
Technisch maakt het voor de performance verder meestal weinig uit.
Het origineel verdwijnt vanzelf zodra het script is voltooid. Wil je het in een eerder stadium verwijderen, dan kun je Praktisch voordeel daarvan is in dit geval vooral dat je fouten uitsluit: omdat al een kopie is opgeslagen in de (sessie)cache, voorkom je onopgemerkte wijzigingen als je het origineel resoluut verwijdert.
Technisch maakt het voor de performance verder meestal weinig uit.
maar het zetten van het object in de sessie scope is wel correct op die plaats ?
Het hangt verder vooral af van je sessiebeheer. Stel, je hebt een sessieduur van 10 minuten. Dan kan het gebeuren dat iemand die dicht bij het werk woont, twee sessies krijgt. Idem dito voor iemand die thuis de werkplek-met-pc verruilt voor de luie-stoel-met-tablet: dan heb je twee devices en twee sessies.
Maar uit je opmerking neem ik aan dat er dan dus andere manieren zijn ? Of is het een beetje "standaard" dat je ervanuit gaat dat een gebruiker maar 1 sessie zal gebruiken ?
Voor de sessiecache maakt dat verder weinig uit. Je kunt immers ook in het object dat is opgeslagen in de cache extra beveiligingen inbouwen. Of dat object dan steeds opnieuw wordt gegenereerd of uit de cache wordt hergebruikt, maakt niet uit.
Helemaal top ! Dankjewel voor je hulp !