[PHP] Classes: wanneer gebruiken van pointer ?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben nu een aardig tijdje met PHP bezig, en bij de scripts die ik wel eens zie, zie ik soms bij classes/functions een & staan...

Het gebruik op zich snap ik wel (dat ie een geheugenadres in de var zet ipv de waarde, zodat ze in feite 'gekoppeld' zijn), maar mijn vraag is: wanneer gebruik je nou zo'n pointer? Je kunt toch ook een return geven?

Dit snap ik wel:
PHP:
1
2
3
4
5
6
7
8
9
function test(&$foo) {
     $foo++;
}

$bar = 3;
test($bar);

echo $bar;
/* Vervolgens heeft $bar een waarde van 4 */

Dit snap ik, maar ik snap dus niet wanneer het gebruikt wordt ?

Geraadpleegde topics: [rml][ PHP] Wanneer een & gebruiken ???[/rml], maar daar kan ik ook niet zoveel wijs uit worden.

Iemand nog andere howto's ? (En ja: Search/PHPBuilder.com/Google heb ik al geprobeerd)... :)

[ Voor 4% gewijzigd door Verwijderd op 15-01-2003 08:25 ]


Acties:
  • 0 Henk 'm!

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 17-09 07:55

thomaske

» » » » » »

Bij het voorbeeldje wat jij geeft heeft het inderdaad niet veel meerwaarde. Maar stel ik heb een database-object welke gebruikt moet worden door een ander object/functie. Wanneer ik deze dan zonder & meegeef aan een functie (call by value) wordt het hele object gekopieerd, terwijl wanneer je wel een & gebruikt (call by reference) alleen de pointer naar het object wordt meegegeven, dat scheelt een hoop geheugenruimte..

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


Acties:
  • 0 Henk 'm!

Verwijderd

Stel je wilt meerdere variables returnen? Dan is dit de enige oplossing.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

thomaske schreef op 15 januari 2003 @ 09:35:
Wanneer ik deze dan zonder & meegeef aan een functie (call by value) wordt het hele object gekopieerd, terwijl wanneer je wel een & gebruikt (call by reference) alleen de pointer naar het object wordt meegegeven, dat scheelt een hoop geheugenruimte..
PHP maakt geen kopie als het object niet gewijzigd wordt, bij de eerste wijziging wordt het pas gekopieerd (met call-by-value).
Een beter verhaal bij jouw voorbeeld is bv als die functie de database sluit. Je hoofdprogramma zit dan met een open database object, terwijl de feitelijke connectie als gesloten is. Niet echt fijn.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
thomaske schreef op 15 January 2003 @ 09:35:
Bij het voorbeeldje wat jij geeft heeft het inderdaad niet veel meerwaarde. Maar stel ik heb een database-object welke gebruikt moet worden door een ander object/functie. Wanneer ik deze dan zonder & meegeef aan een functie (call by value) wordt het hele object gekopieerd, terwijl wanneer je wel een & gebruikt (call by reference) alleen de pointer naar het object wordt meegegeven, dat scheelt een hoop geheugenruimte..
Ah ok, dus die & heeft wel invloed op de snelheid van een script ?

Hmm, niemand een leuk voorbeeld-script(je) waarin het gebruik van die & duidelijk wordt?

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op 15 January 2003 @ 16:11:
[...]
Ah ok, dus die & heeft wel invloed op de snelheid van een script ?

Hmm, niemand een leuk voorbeeld-script(je) waarin het gebruik van die & duidelijk wordt?

Stel je hebt een gigantisch groot object. Zonder & wordt er een kopie gemaakt, en dat kost dus veel tijd/geheugen. Met & is het natuurlijk vele malen sneller in zo'n geval.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op 15 januari 2003 @ 16:13:

[...]

Stel je hebt een gigantisch groot object. Zonder & wordt er een kopie gemaakt, en dat kost dus veel tijd/geheugen. Met & is het natuurlijk vele malen sneller in zo'n geval.
Ah, ok :) Ik heb t ook ff getest met een scrippie en tijdmeting, en hij is bij 100.000x loopen 0,1 sec sneller :P (gewoon met $bar++ ed)...

Maar nu een "echt" voorbeeld in een dbase-class bv... Ik heb een dbase-class gemaakt, maar daarbij maak ik geen gebruik van pointers... Hoe zou ik dat daar kunnen verwezelijken ?

Acties:
  • 0 Henk 'm!

  • S_E_B
  • Registratie: Oktober 2002
  • Laatst online: 02-09-2015

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Beter voorbeeld:

PHP:
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
class Blaat
{
    var $bla;

    Blaat ()
    {
        $this->bla = 0;
    }

    function doeIets ()
    {
        $this->bla++;
        echo "bla = " . $this->bla . "\n";
    }
}

function doeNogIets ($b)
{
    $b->doeIets ();
}


$b = new Blaat ();
$b->doeIets ();
doeNogIets ($b);
$b->doeIets ();


je maakt hier een object aan, die je vervolgens bewerkt. Maar bij de aanroep van doeNogIets () wordt een kopie gemaakt, waardoor $b dus niet veranderd is. Dit lijkt me niet helemaal wat je wilt, je geeft immers het object mee zodat dat veranderd kan worden

de output hiervan is overigens:
code:
1
2
3
bla=1
bla=2
bla=2


onder voorbehoud van typfouten ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Rotjeknor
  • Registratie: April 2001
  • Laatst online: 01-04-2023
Verwijderd schreef op 15 januari 2003 @ 11:31:
Stel je wilt meerdere variables returnen? Dan is dit de enige oplossing.
Precies!

Nog maar ff een voorbeeld zoals ik m gebruik:
PHP:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
function get_current_edition(&$year, &$month, &$month_name, $approved = "1", $get_edition_id = "0")
{
  $query = "select
              max(year)
            from
              editions
            where
              approved = '$approved'
            ;";
  $result_last_year = queryv($query);
  list($year) = mysql_fetch_row($result_last_year);

  $query = "select
              max(month)
            from
              editions
            where
              approved = '$approved' and
              year = '$year'
            ;";
  $result_last_month = queryv($query);
  list($month) = mysql_fetch_row($result_last_month);
  $month_name = get_month_name($month);

  if ($get_edition_id)
  {
    $query = "select
                id
              from
                editions
              where
                month = '$month' and
                year = '$year'
              ;";
    $result_last_edition = queryv($query);
    list($edition_id) = mysql_fetch_row($result_last_edition);
  }
  return $edition_id;
}

Waarbij je m dus aanspreekt met:
PHP:
1
$edition_id = get_current_edition($year, $month, $month_name, 0, 1);

Hierbij maak je dus zowel gebruik van de return value als de pointers.

Ook Knor is aangestoken met het ligfietsvirus!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
.oisyn schreef op 15 januari 2003 @ 16:43:
Beter voorbeeld:

PHP:
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
class Blaat
{
    var $bla;

    Blaat ()
    {
        $this->bla = 0;
    }

    function doeIets ()
    {
        $this->bla++;
        echo "bla = " . $this->bla . "\n";
    }
}

function doeNogIets ($b)
{
    $b->doeIets ();
}


$b = new Blaat ();
$b->doeIets ();
doeNogIets ($b);
$b->doeIets ();


je maakt hier een object aan, die je vervolgens bewerkt. Maar bij de aanroep van doeNogIets () wordt een kopie gemaakt, waardoor $b dus niet veranderd is. Dit lijkt me niet helemaal wat je wilt, je geeft immers het object mee zodat dat veranderd kan worden

de output hiervan is overigens:
code:
1
2
3
bla=1
bla=2
bla=2


<span style="font-size:8pt">onder voorbehoud van typfouten ;)</span>
PHP:
1
2
3
4
function doeNogIets (&$b) 
{ 
    $b->doeIets (); 
}


Foutje :P en je was 'function' vergeten bij Blaat() :P Maar goed, ik begin het te snappen :) Maar het geheel begrijpen wil het nog niet... De toepassing ervan is nog niet geheel duidelijk, naast het returnen van meerdere waardes dan...

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 15 January 2003 @ 17:43:
[...]

PHP:
1
2
3
4
function doeNogIets (&$b) 
{ 
    $b->doeIets (); 
}


Foutje :P


nee, ik probeerde juist te demonstreren dat het fout ging als je _geen_ referentie meegaf :)
Dat 2e foutje kan wel kloppen, ben niet zo'n held in php :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Toch hebben jullie een verkeerd beeld van php "references". Het zijn namelijk geen pointers en ook geen references in de C++ zin van het woord. Het zijn aliases. Je kent een andere, extra, naam toe aan een bestaande variabele.

Als je objecten by-value passed wordt er in eerste instantie geen kopie gemaakt. PHP gebruikt "lazy copying". Vandaar ook dat dit:

PHP:
1
$a = new Foo();


Geen overhead van een kopie heeft. Er zijn in principe twee objecten aanwezig, "new Foo()" en "$a". Als je het zo schrijft:

PHP:
1
$a &= new Foo();


Is er maar 1 object aanwezig, en is "$a" een andere naam voor dit object.

Bottomline, zie "ampersands" als een andere naam voor een object, nit als een pointer naar een object.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Zoijar schreef op 15 januari 2003 @ 18:04:
Toch hebben jullie een verkeerd beeld van php "references". Het zijn namelijk geen pointers en ook geen references in de C++ zin van het woord. Het zijn aliases. Je kent een andere, extra, naam toe aan een bestaande variabele.

Als je objecten by-value passed wordt er in eerste instantie geen kopie gemaakt. PHP gebruikt "lazy copying". Vandaar ook dat dit:

PHP:
1
$a = new Foo();


Geen overhead van een kopie heeft. Er zijn in principe twee objecten aanwezig, "new Foo()" en "$a". Als je het zo schrijft:

PHP:
1
$a &= new Foo();


Is er maar 1 object aanwezig, en is "$a" een andere naam voor dit object.

Bottomline, zie "ampersands" als een andere naam voor een object, nit als een pointer naar een object.
Dank u _/-\o_ Dit is helder :) Ik was volgens mij in de war met C (roelende taal, ben er net 3 weken mee bezig :P)

Maar ik mis, zoals ik eerder als zei, de 'echte' toepassing ervan ?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Oh ja, wat is dit dan?
PHP:
1
2
3
function &test() {
     /* doe iets */
}

Of kan dit helemaal niet ?

[ Voor 3% gewijzigd door Verwijderd op 15-01-2003 18:16 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Zoijar schreef op 15 januari 2003 @ 18:04:
Bottomline, zie "ampersands" als een andere naam voor een object, nit als een pointer naar een object.

Dat ze technisch verschillen maakt niet uit :P
Het is een soort pointer en als je uit de C wereld komt is 'het is een soort pointer' de simpelste uitleg die je kan geven...
En de kans dat het dmv een pointer binnen c++ opgelost wordt is vrij groot...

Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
dit topic gaat hier ook over en gaat zelfs over een praktische toepassing van &

en deze is volkomen een volkomen nutteloos maar werkend script en ook vanalles met &'n doet. (let overigens dat de &'n in de addchild method niet perse nodig zijn voor de in het testscript gedraaide test, maar wel voor het bouwen van een tree zonder gekopieerde objecten)

[ Voor 62% gewijzigd door Genoil op 15-01-2003 18:52 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Dit is toch wel een pijnlijke fout hoor, &= betekent iets heel anders dan =&

Voorbeeld:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
   function &get_var ( $v )
   {
      return $v;
   }

   $a = 6;
   $b = 3;
   
   $a =& get_var ( $b );
   
   echo $a;
?>

Vervang =& maar eens door &=

[ Voor 7% gewijzigd door Verwijderd op 15-01-2003 18:39 ]


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op 15 januari 2003 @ 18:16:
Oh ja, wat is dit dan?
PHP:
1
2
3
function &test() {
     /* doe iets */
}

Of kan dit helemaal niet ?
Ja dat kan en is ook meteen een van de meest vage PHP functionaliteiten. Je kan daarmee een object retourneren [b]zonder[b] een kopie ervan te maken.
In bv C is dit een grove fout, vanwege pointer scope regels. Je kan/mag daar niet vanuit iets met een grotere scope iets met een kleinere scope aanspreken.

Dit is een goed voorbeeld: (en geeft meteen een real world situatie aan waar je aliases gebruikt)

PHP:
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
27
28
29
30
31
32
33
    function dispatch($action, &$vars) {
        if ($action != '' && isSet($this->registry[$action])) {
            $entry = &$this->registry[$action];
            
            $params = array();
            foreach($entry['params'] AS $k => $v) {
                if (isSet($vars[$k])) {
                    $params[$k] = $vars[$k];
                } else if ($v != '') {
                    $params[$k] = $v;
                } else {
                    //error
                    return false;
                }
            }

            if (is_object($obj = &$this->factory($entry['class']))) {
                return $obj->$entry['function']($this->pass, $params);
            } else return false;
        } else {
            return false;
        }
    }

    function &factory($classname) {
        $classpath = 'class/'.$classname.'.class.php';

        if (file_exists($classpath)) {
            require_once($classpath);
            $obj = &new $classname($this->pass);
            return $obj;
        } else return false;
    }


Ik denk trouwens niet dat aliases als C++ pointer worden geimplementeerd in de interpreter. Ik denk eerder dat het indices in de symbol table zijn (wat in feite wel weer opgevat kan worden als pointer zonder base) Maar dat weet ik niet zeker, heb nog nooit de php source gezien.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op 15 January 2003 @ 18:38:

[...]

Dit is toch wel een pijnlijke fout hoor, &= betekent iets heel anders dan =&
Vervang =& maar eens door &=
Oops |:( ja type foutje, je hebt helemaal gelijk.

[ Voor 26% gewijzigd door Zoijar op 15-01-2003 18:40 ]


Acties:
  • 0 Henk 'm!

Verwijderd

oke....
ik ben geen prog held. heb dit allemaal doorgelezen.
maar er rest mij nog 1 vraag:
HOE gebruik ik dit?
wanneer wel, wanneer juist niet?
(hopelijk ben ik niet al te vervelend :))
vin het namelijk wel interresant, ben de laatste tijd namelijk nogal aan het spelen met classes. en ik merk dat ze al gauw aardig wat laadtijd vreten. dit zit hmm dus vast in mijn manier van toepassen.
hoping to get a clear answer 8)
laters

Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
ik denk niet dat het verkorten van laadtijd een overweging is m.b.t. het gebruik van references. Ze zijn bijvoorbeeld wel goed van toepassing in gevallen wanneer je dezelfde variabele (het zij een primitief, array of object), in meerdere datastructuren wilt onderbrengen, zonder dat de variabele "gecloned" wordt.

Stel je hebt bijvoorbeeld een verzameling objecten, die je tegelijkertijd in een boomstructuur en een gesorteerde lijst wilt onderbrengen, waarbij je als je iets aan het object wijzigt via de boom, de veranderingen worden meegenomen in de lijst en vice versa.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Kwam nog een goed voorbeeldje tegen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
    function Login(&$CDatabase, &$CSession) {
        $this->challenge = &$CSession->vars['login_challenge'];
        $this->user = &$CSession->vars['login_user'];
        if (!isSet($CSession->vars['login'])) {
            $CSession->vars['login'] = true;
            $this->challenge = 0;
            $this->user = '';
            $this->seed();
        }

        $this->CDatabase = &$CDatabase;
        $this->allows = array();
    }


De member var $this->user is nu een andere naam voor de sessie variabele login_user. De member var is nu dus atomatisch "persistent", op volgende page views blijft hij hetzelfde. Als je geen ampersand had gebruikt, kreeg je een kopie van de sessie var en zouden wijzigingen verloren gaan tussen twee page views.

Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
Verwijderd schreef op 15 januari 2003 @ 11:31:
Stel je wilt meerdere variables returnen? Dan is dit de enige oplossing.
Het returnen van een array ;)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Genoil schreef op 16 januari 2003 @ 11:44:
ik denk niet dat het verkorten van laadtijd een overweging is m.b.t. het gebruik van references.
Das een slecht argument ervoor, imho :)
Ze zijn bijvoorbeeld wel goed van toepassing in gevallen wanneer je dezelfde variabele (het zij een primitief, array of object), in meerdere datastructuren wilt onderbrengen, zonder dat de variabele "gecloned" wordt.

Stel je hebt bijvoorbeeld een verzameling objecten, die je tegelijkertijd in een boomstructuur en een gesorteerde lijst wilt onderbrengen, waarbij je als je iets aan het object wijzigt via de boom, de veranderingen worden meegenomen in de lijst en vice versa.

En dat is wel een mooi voorbeeld :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Zoijar schreef op 16 January 2003 @ 11:57:
Kwam nog een goed voorbeeldje tegen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
    function Login(&$CDatabase, &$CSession) {
        $this->challenge = &$CSession->vars['login_challenge'];
        $this->user = &$CSession->vars['login_user'];
        if (!isSet($CSession->vars['login'])) {
            $CSession->vars['login'] = true;
            $this->challenge = 0;
            $this->user = '';
            $this->seed();
        }

        $this->CDatabase = &$CDatabase;
        $this->allows = array();
    }


De member var $this->user is nu een andere naam voor de sessie variabele login_user. De member var is nu dus atomatisch "persistent", op volgende page views blijft hij hetzelfde. Als je geen ampersand had gebruikt, kreeg je een kopie van de sessie var en zouden wijzigingen verloren gaan tussen twee page views.
Het begint te dagen, maar nog niet helemaal :( Niemand een iets makkelijker voorbeeld om mee te beginnen? :P Blijft de data in een class bestaan als je je page refresht ? Want dat zegt ^^ nl :?

Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Verwijderd schreef op 16 januari 2003 @ 16:01:
[...]

Het begint te dagen, maar nog niet helemaal :( Niemand een iets makkelijker voorbeeld om mee te beginnen? :P Blijft de data in een class bestaan als je je page refresht ? Want dat zegt ^^ nl :?
Het blijft in ^^'s geval persistent, omdat ie het object in een sessievar gooit (vermoed ik). Nogmaals, ik heb hier een kant en klaar voorbeeld van een persistent object-tree, met gebruik van references. Niet bijzonder nuttig, maar het werkt wel aardig.

[ Voor 5% gewijzigd door Genoil op 16-01-2003 18:00 ]


Acties:
  • 0 Henk 'm!

Verwijderd

ik denk dat ik het nu wel snap ja :)
je hebt meerde objecten hebt die invloed op elkaar hebben, zonder dus dat ze op copieen van elkaar werken. dit heeft tot effect dat de actie van het ene object DIRECT uitwerking kan hebben op de ander zonder dat je eerst weer die variable aan dat object hoeft door te geven. zeg maar interactie tussen objecten.
(plz correct me if im wrong 8))

leuke dingen om te weten trouwens :)
zijn van die dingen die je verder helpen , ook buiten php :)

[ Voor 5% gewijzigd door Verwijderd op 17-01-2003 06:08 . Reden: typo's, STUPID typo's! ]


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Verwijderd schreef op 17 januari 2003 @ 06:03:
ik denk dat ik het nu wel snap ja :)
je hebt meerde objecten hebt die invloed op elkaar hebben, zonder dus dat ze op copieen van elkaar werken. dit heeft tot effect dat de actie van het ene object DIRECT uitwerking kan hebben op de ander zonder dat je eerst weer die variable aan dat object hoeft door te geven. zeg maar interactie tussen objecten.
(plz correct me if im wrong 8))

leuke dingen om te weten trouwens :)
zijn van die dingen die je verder helpen , ook buiten php :)
Ja dat dekt de lading wel zo'n beetje...
Buiten PHP, zoals in een taal als Java, zijn "passing en returnning by reference" echter eerder regel dan uitzondering.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hmm, nog ff voor de duidelijkheid ?

Je zet in de function-regel de &, en in de function roep je var gewoon aan? Dus zo?
PHP:
1
2
3
4
5
6
function test(&$var) {
     $var++;
}

$foo = 1;
test($foo)


En hetzelfde bij objecten ?
PHP:
1
2
3
4
5
6
function test(&$db) {
     $db->Query("blaat");
}

$d = new db();
test($d);


/me begint het volgens te snappen :P
Pagina: 1