Free result & pass by refference vraagje

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Johan K

Johan K

28/03/2013 18:28:16
Quote Anchor link
Om het maar even simpel te houden,

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
<?php

  class Result{
    public $rs;
    
    function
foo($var){
      return mysql_free_result($var); # memory leak cause of copy of var.
    }
    
    function
bar(&$var){
      return mysql_free_result($var); # no memory leak; pass by refference.
    }
    
    function
__destruct(){
      mysql_free_result($this->rs);   # avoid memory leak completely.
    }
  }


?>


Dit is correct?
 
PHP hulp

PHP hulp

28/11/2024 03:57:52
 
Johan K

Johan K

29/03/2013 21:45:59
Quote Anchor link
Ik zoek toch nog een beetje conformatie, aangezien dit vaak gebruikt gaat worden in mijn script.

Alvast bedankt,
 
Frank Nietbelangrijk

Frank Nietbelangrijk

29/03/2013 22:47:54
Quote Anchor link
Hoi Johan,

wat betreft de eerste functie: ja de variabele wordt gekopieerd maar na het verlaten van de functie wordt die kopie ook gelijk weer vrijgegeven. dus is het slechts een zeer kortstondig geheugen verbruik.
Bij de tweede gebeurt bijna hetzelfde zij het dat niet de waarde van een variabele gekopieerd wordt maar het geheugen-adres. ook deze variabele 'verdampt' bij het verlaten van de functie. bij nummer drie zien we in tegenstelling tot de eerste twee een OOP methode. wanneer het geheugen vrij wordt gemaakt wordt eerst de destructor aangeroepen om eventuele 'processen' netjes te beëindigen. Belangrijk is dat je begrijpt dat hier een hele instantie van een class vrijgegeven wordt en niet alleen de variabelen van één functie.

Feitelijk maakt het dus niet zo veel uit welke methode je kiest. Daarbij duurt een gemiddeld php script hooguit enkele seconden waarna ALTIJD al het geheugen van het script weer vrijgegeven wordt, in tegenstelling tot een applicatie die dagen of maanden kan draaien.
Gewijzigd op 29/03/2013 22:49:26 door Frank Nietbelangrijk
 
Johan K

Johan K

29/03/2013 23:14:44
Quote Anchor link
Hey Frank,

Misschien had ik even iets meer sample code moeten geven, want wat je zegt is inderdaad waar voor de eerste twee, mijn excuses.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php

  $foobar
= new Result();
  $foobar->rs = mysql_query("some very interesting query");

  $foobar->foo($foobar->rs); # memory leak, copy of var.
  $foobar->bar($foobar->rs); # no memory leak.
  
  # script ended, destructor is called which frees the result of null now.
  # But if bar() wasn't called beforehand it would have leaked without this.


?>


Maar wat ik niet wist, dat alles vrijgegeven word aan het einde van het script zelfs na het niet vrijmaken van het de result; wat is dan het nut aan die functie?

Aangezien een PHP scriptje inderdaad niet lang moet draaien (en als het langer moet, doe je het naar mijn idee niet in de juiste taal) en alles word vrijgegeven dan is dit in principe overbodig in zijn geheel. Theoretisch zou het zelfs ten koste gaan van de render tijd van je pagina.

Of zit ik hier dan foutief te denken?
Gewijzigd op 29/03/2013 23:26:03 door Johan K
 
Frank Nietbelangrijk

Frank Nietbelangrijk

29/03/2013 23:40:05
Quote Anchor link
nee wat je nu denkt is juist. Ik doe dan ook nooit mysql_free_result() aanroepen. je kunt zelfs op php.net nalezen dat dit automatisch gebeurt. Alleen als je een script schrijft waarin velen malen een nieuw result wordt aangemaakt kun je overwegen of het niet verstandig is om het oude result eerst vrij te geven.
 
Johan K

Johan K

30/03/2013 00:16:49
Quote Anchor link
Bedankt Frank,

Nu was dit van belang om niet door te kunnen gaan, maar dan weet ik dit voor persoonlijk gebruik.
Dit script is min of meer als een example code voor een sollicitatie, en natuurlijk om het in de resources hier op phphulp te posten want het word naar mijn idee een zeer interessant script.

PDO is fijn om mee te werken, maar ik probeer het compacter te maken.

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
<?php

  $read
= new MySQL($host, $user, $pass, $db);
  $write = new Postgrsql($host, $user, $pass, $db);

  try{
    $read->select($what, $table, $read->args(
      'user' = $yourusername,                  // insert $yourusername as is.
      'pass' = array('password', $read::post), // will get the value from $POST[] auto escaped.
      'somval' = array('myint', $read::post | $read::int)   // convert $someval to an integer from post array.
    ));

    # convert query to:
    # "select $what from $table where user = '$yourusername', pass = '$password', someval = '0'"

  } catch (ConnectionException $e){
    die("error connecting to database");
  }
catch (DatabaseExcveption $e){
    die("error in query" . $e->getMessage());
  }
catch (Exception $e){
    die ("unhandled exception");
  }


?>


Dit is even freehand geschreven, kunnen fouten inzitten. '

Elke database type kan geweizigt worden per classe, en kan voor elke database gebruikt worden die ondersteund word in php.
Gewijzigd op 30/03/2013 00:28:22 door Johan K
 
Ward van der Put
Moderator

Ward van der Put

30/03/2013 09:03:09
Quote Anchor link
Frank Nietbelangrijk op 29/03/2013 23:40:05:
nee wat je nu denkt is juist. Ik doe dan ook nooit mysql_free_result() aanroepen. je kunt zelfs op php.net nalezen dat dit automatisch gebeurt. Alleen als je een script schrijft waarin velen malen een nieuw result wordt aangemaakt kun je overwegen of het niet verstandig is om het oude result eerst vrij te geven.

Misschien even toevoegen dat bij mysqli::query() het resultaat uit niet één maar twee resources bestaat als je een query met SELECT uitvoert: een mysqli_result-object in PHP maar ook een bijbehorende resultaatset in MySQL. Het resultaat in PHP is dan geen complete resultaatset, maar meer een handle die aangrijpt op de resultaatset van de databaseserver.

Daarmee heb je naast het object in PHP dus potentieel een tweede geheugenlek: zolang je de resultaatset niet opruimt, blijft deze beschikbaar op de databaseserver. Mede daarom is het toch wel aan te bevelen altijd actief mysqli_result::free() te gebruiken zodra je de resultaatset niet meer nodig hebt.
Gewijzigd op 30/03/2013 09:03:45 door Ward van der Put
 
Frank Nietbelangrijk

Frank Nietbelangrijk

30/03/2013 09:19:18
Quote Anchor link
Ward,

net even bekeken op php net. Bij mysqli wordt inderdaad aanbevolen om altijd mysqli_result::free te gebruiken. Bij mysql_free_result niet.

Dit is dan dus een verschil tussen deze twee?
 
Ward van der Put
Moderator

Ward van der Put

30/03/2013 09:47:41
Quote Anchor link
Frank, dat weet ik niet precies. Mogelijk hangt het samen met de wijze waarop de resultaatset verder kan worden afgehandeld na het uitvoeren van een SELECT-query met mysqli::query(): “For non-DML queries (not INSERT, UPDATE or DELETE), this function is similar to calling mysqli_real_query() followed by either mysqli_use_result() or mysqli_store_result().”

Met andere woorden: er wordt een resultaatset klaargezet op de databaseserver, niet in PHP. Ook bij klassiek mysql in plaats van mysqli zou ik mysql_free_result() gebruiken na een SELECT. Je kunt webserver en databaseserver zien als twee systemen die samenwerken. Na een SELECT staat de resultaatset paraat op de databaseserver, niet de webserver. Een communicatiemechanisme (het PHP-object voor de resultaatset) kopieert daaruit vervolgens data naar je applicatie. Het geheugen dat wordt gebruikt voor het PHP-object bevat geen complete kopie van de resultaatset op de databaseserver.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

30/03/2013 11:08:40
Quote Anchor link
dank je Ward.
 



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.