/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Hvad er PHP's årsag til erklæring af attri~
Fra : Per Thomsen


Dato : 27-07-01 00:18

Attributter, Medlems-variable, Klasse-variable, de har sikker mange
flere navne, jeg
kalder dem attributter.

Jeg er klar over at PHPs OOP på mange måder er hmm... mangelfuld, men
jeg undrer mig _meget_ over PHP's implementering af attributter.
Det virker nærmest som om at de eneste formål med at erklære dem er at
dokumentere klassen (Ikke at det ikke er en fornuftigt ting).

Nedenstående kildekode outputter:
object(test)(0) { }
object(test)(1) { ["attrib"]=> int(1) }
object(test)(0) { }

Dvs. selv-om jeg har eklæret attributen $attrib, findes den faktisk ikke
i mit objekt, før jeg giver den en værdi, og ydermere kan jeg fjerne den
igen, fra mit objekt.
Man kunne så måske sige: "Nå ja..., men hvad så hvis du initialiserer
den med en værdi?"
Tjah, hvis jeg f.eks. initialiserer den til 3 giver mit script følgende
output:
object(test)(1) { ["attrib"]=> int(3) }
object(test)(1) { ["attrib"]=> int(1) }
object(test)(0) { }

I direkte modsætning til hvad manualen siger, kan jeg faktisk ændre dens
værdi, men ikke nok med det jeg kan fjerne den helt fra objektet.
Jeg kunne lige så godt have haft en constructor, der satte $this->attrib
= 3

For at gøre det endnu mere mystisk kan jeg helt udelade erklæringen af
attributten, og jeg vil få fuldstændig samme output, som i første
tilfælde.

Jeg kan ydermere til enhver tid, tilføje en attribut til klassen såvel
i, som uden for klassen/objektet.
( "$T->nyAttrib = 3" - giver ingen parse error, der kommer blot en
attribut der hedder nyAttrib).

Jeg har også prøvet at anvende funktionen get_object_vars() , for at se
om PHP 'gemte' nogle informationer, som ikke var tilgængelige i
variablen, men jeg får fuldstændig samme opførsel.

Såvidt jeg kan se, er det eneste formål med 'var' at man kan
initialisere sine attributter, men det kan man jo også gøre i
constructor'en.

Jeg står tilbage med spørgsmålet: kan det virkelige passe at de har
implementeret en language-construct, som kan evalueres på en sådan
måde, at fortolkeren ikke bruger den til noget som helst.

Jeg håber at nogen kan hjælpe med at afklare denne mærkelige opførsel,
inden jeg dykker ned i source-koden til PHP-fortolkeren.
(Måske nogen der allerede har været der?).

MVH Per Thomsen
http://www.pert.dk/


--- kildekode start
class Test {

var $attrib;

function set_attrib() {
$this->attrib = 1;
}

function unset_attrib() {
unset($this->attrib);
}

}

$T = new Test();
var_dump($T);
echo "<BR>\n";

$T->set_attrib();
var_dump($T);
echo "<BR>\n";

$T->unset_attrib();
var_dump($T);
echo "<BR>\n";
--- kildekode stop


 
 
Anders Johannsen (27-07-2001)
Kommentar
Fra : Anders Johannsen


Dato : 27-07-01 01:07

In article <9jq8pb$qdn$1@sunsite.dk>, "Per Thomsen" <pert@pert.dk> wrote:

> Attributter, Medlems-variable, Klasse-variable, de har sikker mange
> flere navne, jeg
> kalder dem attributter.

Der er normalt forskel på klassevariabler og instansvariabler.

> I direkte modsætning til hvad manualen siger, kan jeg faktisk ændre dens
> værdi, men ikke nok med det jeg kan fjerne den helt fra objektet. Jeg
> kunne lige så godt have haft en constructor, der satte $this->attrib = 3

Af interesse: Kan jeg få en reference til manualen?

> Jeg kan ydermere til enhver tid, tilføje en attribut til klassen såvel
> i, som uden for klassen/objektet.
> ( "$T->nyAttrib = 3" - giver ingen parse error, der kommer blot en
> attribut der hedder nyAttrib).

Ja? PHPs implementation giver ikke mange af de fordele man normalt vinder
med OO.

> Jeg håber at nogen kan hjælpe med at afklare denne mærkelige opførsel,
> inden jeg dykker ned i source-koden til PHP-fortolkeren. (Måske nogen
> der allerede har været der?).

Lad os vide hvad du finder.

/A

Per Thomsen (27-07-2001)
Kommentar
Fra : Per Thomsen


Dato : 27-07-01 07:22


"Anders Johannsen" <anders@ignition.dk> skrev:
> In article <9jq8pb$qdn$1@sunsite.dk>, "Per Thomsen" <pert@pert.dk>
wrote:
>
[snip]

> > I direkte modsætning til hvad manualen siger, kan jeg faktisk ændre
dens
> > værdi, men ikke nok med det jeg kan fjerne den helt fra objektet.
Jeg
> > kunne lige så godt have haft en constructor, der satte $this->attrib
= 3
>
> Af interesse: Kan jeg få en reference til manualen?

http://www.php.net/manual/en/language.oop.php
I "Note:" lige under "Caution" boksen.

Når jeg læser det igen, kan jeg godt se, at det de mener,
nok er, at man ikke kan evaluere udtryk, men kun initiliasiere
dem til konstanter (litteraler?).

[snip]
> > Jeg håber at nogen kan hjælpe med at afklare denne mærkelige
opførsel,
> > inden jeg dykker ned i source-koden til PHP-fortolkeren. (Måske
nogen
> > der allerede har været der?).
>
> Lad os vide hvad du finder.

will do.

Per Thomsen
http://www.pert.dk/


Per Thomsen (29-07-2001)
Kommentar
Fra : Per Thomsen


Dato : 29-07-01 23:07

[snip]
> > > Jeg håber at nogen kan hjælpe med at afklare denne mærkelige
> opførsel,
> > > inden jeg dykker ned i source-koden til PHP-fortolkeren. (Måske
> nogen
> > > der allerede har været der?).
> >
> > Lad os vide hvad du finder.
>
> will do.

Så her er hvad jeg fandt.

I Zend/zend_language_parser.c (linie 2299 - 2310):

case 142:
{ zend_do_declare_property(&yyvsp[0], NULL CLS_CC); ;
break;}
case 143:
{ zend_do_declare_property(&yyvsp[-2], &yyvsp[0] CLS_CC); ;
break;}
case 144:
{ zend_do_declare_property(&yyvsp[0], NULL CLS_CC); ;
break;}
case 145:
{ zend_do_declare_property(&yyvsp[-2], &yyvsp[0] CLS_CC); ;
break;}

Som jeg umiddelbart vil mene svarer til de 4 tilfælde:
var $attrib;
var $attrib = "something"
$this->attrib;
$this->attrib = "something";

Læg mærke til at i case 142 og 144 er andet argument NULL

I filen Zend/zend_compile.c finder vi så funktionen
zend_do_declare_property i linierne: 1611 - 1622:

void zend_do_declare_property(znode *var_name, znode *value CLS_DC)
{
if (value) {
zval *property;

ALLOC_ZVAL(property);

*property = value->u.constant;
zend_hash_update(&CG(active_class_entry)->default_properties,
var_name->u.constant.value.str.val,
var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL);
}
FREE_PNODE(var_name);
}

I første statement (if(value)...) ligger humlen så, i tilfældene 142 og
144, vil dette være falsk
og ganske som formodet.. bliver erklæringen så ikke brugt til noget som
helst.

Men hvorfor???

Jeg havde håbet at finde nogle kommentarer i kildekoden, der fortalte
noget, men desværre.
Jeg står tilbage med konstateringen, at det ikke er ulovligt at erklære
en attribut, uden en værdi, men det gør heller ingen til ved parseren.
Og hvorfor det er sådan kan kun blive et gæt.

Jeg gætter på at årsagen til denne opførsel skyldes PHP's
type-håndtering (eller manglen på samme). Når man erklærer en attribut
har PHP ingen ide om hvor meget hukommelse, der skal reserveres til
denne, først i det øjeblik man giver den en værdi, kan der reserveres
plads i hukommelsen, hvilket så må ske faktisk _hver_ gang man giver
attributten en værdi (der findes 2 funktioner vedr. properties nemlig
zend_do_declare_propety() og zend_fetch_property(), men ingen
zend_set_property). I og med at en attribut bliver deklareret hver gang
man tilgår den, kunne man godt have valgt at håndtere attributter
anderledes end variable.

Man kunne have valgt altid at reservere f.eks. en byte til en attribut,
og kontrollere om attributten eksisterede før man skrev til den, dette
ville dog ikke stemme særlig godt overens med PHPs "normale" variable,
som man jo også kan genere on-the-fly.

Og man kunne også mene at den måde PHP gør det på er en optimering mht
til hukommelsesbrug.

Måske ligger årsagen i hash funktionerne, men så langt har jeg ikke lyst
til at dykke.
Jeg er tilfreds med hvad jeg har fundet ud af (eller rettere jeg er
tilfred med at jeg har fundet ud af det), og fastholder at det i det
mindste til enhver tid er god programmerings-skik at deklarere sine
attributter, og hvem ved, måske laver de opførslen om i en fremtidig
version af PHP.

MVH Per Thomsen,
http://www.pert.dk/


Søg
Reklame
Statistik
Spørgsmål : 177508
Tips : 31968
Nyheder : 719565
Indlæg : 6408575
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste