ontkoppelen variabele
Nou vroeg ik me af of je een variabele ook weer kunt ontkoppelen.
Helaas heb ik geen antwoord.
@Reshad: Helaas, werkt niet.
Wat je kan doen is de variabele overschrijven met een nieuwe variabele, of proberen met unset() hoewel ik het laatste aan twijfel of dat gaat werken..
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
$a = 10;
$b = &$a; // b krijgt als waarde het adres van $a
echo $b . "<br>";
$a = 20;
echo $b . "<br>"; // b heeft nog steeds als waarde het adres van $a; dus $b=20
unset($a); // $a wordt ontkoppeld van zijn eigen adres
$a = 15; // $a is nu een nieuwe variabele en heeft niets meer te maken met de $a van 3 lijnen geleden
echo $b . "<br>"; // b blijft wijzen naar het origineel, waar $a nog steeds 20 is.
?>
$a = 10;
$b = &$a; // b krijgt als waarde het adres van $a
echo $b . "<br>";
$a = 20;
echo $b . "<br>"; // b heeft nog steeds als waarde het adres van $a; dus $b=20
unset($a); // $a wordt ontkoppeld van zijn eigen adres
$a = 15; // $a is nu een nieuwe variabele en heeft niets meer te maken met de $a van 3 lijnen geleden
echo $b . "<br>"; // b blijft wijzen naar het origineel, waar $a nog steeds 20 is.
?>
----------
In c (c++) noemt men dit een pointer.
De beste vergelijking die ik ken, is de MS Windows snelkoppeling.
Een snelkoppeling is een bestand. De content van dat bestand is een adres: het adres waar de snelkoppeling naar moet wijzen.
In dit geval:
$b geef je de waarde: het adres van $a.
Je kan het programma zelf verplaatsen; dan wijst die snelkoppeling niet meer naar het programma, maar naar een adres waar waarschijnlijk niets meer staat.
bedankt voor de reacties, ik ben weer een hoop wijzer geworden :D
zou het overigens ook zo zijn dat na de unset van $a en het geheugen overschreven wordt, $b deze overschreven waarde aanneemt?
Ik denk dat het stuk geheugen niet echt wordt vrijgegeven zolang er 1 of meerdere variabelen naar wijzen.
$b = $a; betekent: neem de waarde van $a en steek ze in $b
$c = &$a; betekent dat $c een snelkoppeling naar $a wordt. Wanneer de waarde van $a wordt aangepast, zal die waarde ook mee veranderen als je $c uitleest.
Als je $a verandert en $b uitleest, zal de waarde van $b niet mee aangepast worden.
Dit is vooral handig om te gebruiken in functies.
Een voorbeeld: Let niet te veel op de nutteloosheid van de functie. Let op het feit dat je, buiten de return, nog een waarde uit de functie kan exporteren door een variabele als referentie mee te geven.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$errorString = '';
echo '$errorString voor de aanroep: '. $errorString .'<br>';
$a = gedeeldDoor(15, 0, $errorString) ;
echo '$errorString na de aanroep: '. $errorString .'<br>';
function gedeeldDoor($teller, $noemer, &$error) {
if ($noemer == 0) {
$error = 'Je mag niet delen door nul';
return false;
}
else {
return $teller/$noemer;
}
}
?>
$errorString = '';
echo '$errorString voor de aanroep: '. $errorString .'<br>';
$a = gedeeldDoor(15, 0, $errorString) ;
echo '$errorString na de aanroep: '. $errorString .'<br>';
function gedeeldDoor($teller, $noemer, &$error) {
if ($noemer == 0) {
$error = 'Je mag niet delen door nul';
return false;
}
else {
return $teller/$noemer;
}
}
?>
Kris Peeters op 23/07/2012 14:25:42:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$errorString = '';
echo '$errorString voor de aanroep: '. $errorString .'<br>';
$a = gedeeldDoor(15, 0, $errorString) ;
echo '$errorString na de aanroep: '. $errorString .'<br>';
function gedeeldDoor($teller, $noemer, &$error) {
if ($noemer == 0) {
$error = 'Je mag niet delen door nul';
return false;
}
else {
return $teller/$noemer;
}
}
?>
$errorString = '';
echo '$errorString voor de aanroep: '. $errorString .'<br>';
$a = gedeeldDoor(15, 0, $errorString) ;
echo '$errorString na de aanroep: '. $errorString .'<br>';
function gedeeldDoor($teller, $noemer, &$error) {
if ($noemer == 0) {
$error = 'Je mag niet delen door nul';
return false;
}
else {
return $teller/$noemer;
}
}
?>
Resultaat: http://codepad.org/inwe8xgX
Maar waarom zou je $b = &$a; gebruiken en niet gewoon $a?
Ik vroeg me af, wat er gebeurt als je $b wijzigt: http://codepad.org/orWPpmlR
Kortom.... $b === $a en blijft dat.
Echt geen blijvende gelijkenis.
Maar wat is dan het voordeel? Behalve 2 waarden uit een functie halen? (Wat ook met global kan)?
Gewijzigd op 30/07/2012 09:26:15 door Eddy E
Maar in functies is het een ander verhaal.
global zien als een alternatief voor een paramater by reference, vind ik niet volledig eerlijk, zelfs al doen ze het zelfde.
Kwestie van best practice maakt dat veel uit.
Functies moet je functioneel schrijven. Je schrijft ze met de gedachte dat ze hergebruikt worden.
Met global beslis je, van binnenin de functie hoe een variabele er buiten moet heten.
Als je een aantal van zo'n functies in een bibliotheek hebt, moet je al bang beginnen worden om bepaalde namen te geven aan variabelen, anders komen ze in de greep van die functies met global vars.
Met de variabele by ref heb je dit probleem niet. Wie de functie gebruikt, kiest volledig zelf of hij die link maakt en hoe die variabele heet (buiten de functie).
Als je een uitgebreidere funtie schrijft en publiceert, wil je dat, wie ze ook gebruikt, er met zijn poten van af blijft.
Gewijzigd op 30/07/2012 10:03:58 door Kris Peeters
Dan is &$iets beter.
Zo zit mysql_error() ook in elkaar zeker? Hij kijkt naar de laaste gemaakte $var uit mysql_query() en gebruikt die in mysql_error()?
Als voorbeeld hé ;).
Dit laatste weet ik niet. Misschien wel, ja. Hiermee zou het kunnen.
mysql_error functie kijkt of je een parameter meegeeft. Zo niet dan roept hij MySG(default_link) aan, dit bevat de laatst gebruikte link die aangemaakt is door de php_mysql_set_default_link functie.
Nog een leuk extraatje: mocht de default_link nog niet bestaat dan heeft hij 2 opties: een connectie error teruggeven of aannemen dat deze functie verkeerd is aangeroepen en gewoon false returnen.
Ook leuk is dat deze functie dus helemaal het error bericht zelf niet returned. Het geeft alleen het cijfer terug van de error message. De PHP default error handler zet deze dan om in een error message.
In de PHP broncode wordt overigens heel erg veel met references gewerkt. Bijv. de functie strpos. Deze krijgt alle parameters bij referentie.
Dat laatste is niet waar. De Nog een leuk extraatje: mocht de default_link nog niet bestaat dan heeft hij 2 opties: een connectie error teruggeven of aannemen dat deze functie verkeerd is aangeroepen en gewoon false returnen.
Ook leuk is dat deze functie dus helemaal het error bericht zelf niet returned. Het geeft alleen het cijfer terug van de error message. De PHP default error handler zet deze dan om in een error message.
In de PHP broncode wordt overigens heel erg veel met references gewerkt. Bijv. de functie strpos. Deze krijgt alle parameters bij referentie.