Noob vraag over instancieren van objecten

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Tijn Snijders

Tijn Snijders

01/07/2014 12:25:10
Quote Anchor link
Als ik bv in de index.php heb staan:


---------
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 ?
 
PHP hulp

PHP hulp

27/12/2024 15:23:08
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 13:17:08
Quote Anchor link
Dat klopt: een object bestaat slechts terwijl het PHP-script wordt uitgevoerd. Is het script voltooid, dan ruimt de garbage collector alles op.

Als je objecten langer houdbaar wilt maken, kun je ze opslaan in een PHP-sessie of een database door ze te serialiseren.
 
Tijn Snijders

Tijn Snijders

01/07/2014 13:22:48
Quote Anchor link
Na een beetje zoeken kom ik op het volgende, waarvan ik niet zeker weet of dat correct is.

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 ?
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 13:41:29
Quote Anchor link
Het kan inderdaad op meerdere manieren.

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)
PHP script in nieuw venster Selecteer het PHP script
1
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);
}

?>


>> 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.
 
Tijn Snijders

Tijn Snijders

01/07/2014 13:55:16
Quote Anchor link
informatie waar ik iets aan heb ! Dank ! Ik ga er mee aan de slag.

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 ?
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 15:02:32
Quote Anchor link
Dan doe je waarschijnlijk iets fout. Laat de code eens zien?

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.
 
Tijn Snijders

Tijn Snijders

01/07/2014 15:10:39
Quote Anchor link
Hier include ik de class en zet hem in de session scope
-----------------------------
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
<?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);
   }

?>

-----------------------------



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 ???
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 15:15:01
Quote Anchor link
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.
 
Tijn Snijders

Tijn Snijders

01/07/2014 15:23:24
Quote Anchor link
ik heb nu $_SESSION['userController'] = serialize($UserController); in de if statement gezet, wanneer de check true is. Dit resulteert in dat ik inderdaad de naam op de pagina zie terug komen als ik van pagina verwissel.

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 ?
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 15:46:09
Quote Anchor link
Het origineel verdwijnt vanzelf zodra het script is voltooid. Wil je het in een eerder stadium verwijderen, dan kun je 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.
 
Tijn Snijders

Tijn Snijders

01/07/2014 15:47:14
Quote Anchor link
maar het zetten van het object in de sessie scope is wel correct op die plaats ?
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 15:54:02
Quote Anchor link
Ja, als je ervan uitgaan dat één sessie bij één gebruiker hoort, is dat correct.

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.
 
Tijn Snijders

Tijn Snijders

01/07/2014 16:16:02
Quote Anchor link
Daar ga ik nu voor het gemak wel even vanuit ja, heel eerlijk gezegt was dat nog niet bij me boven gekomen..

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 ?
 
Ward van der Put
Moderator

Ward van der Put

01/07/2014 16:50:49
Quote Anchor link
Het hangt er in dergelijke gevallen vooral van af wat een user allemaal kan en mag.

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.
 
Tijn Snijders

Tijn Snijders

01/07/2014 17:47:58
Quote Anchor link
Ward... drink een biertje van mij!

Helemaal top ! Dankjewel voor je hulp !
 



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.