/ 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
Mystisk funktion
Fra : Bertel Lund Hansen


Dato : 05-07-05 15:43

Hej alle

Hvorfor returnerer funktionen contains() to værdier?

class Sex {
   var $kategori;
   var $fornavne=Array(); // Fornavne
   function Sex ($kat) {
      $this->kategori=$kat;
   }
   function get_antal () {
      $antal=0;
      foreach ($this->fornavne as $nr => $fornavn)
$antal+=$fornavn->antal;
      return $antal;
   }
   function contains ($name) {
      foreach ($this->fornavne as $nr => $fornavn)
         if ($name==$fornavn->navn) return $nr;
      return -1;
   }
}

Jeg kalder den i følgende stump:

   $name=$temp->fornavn;
   foreach ($sexes as $s => $sex) {
      $num=$sex->contains($name);
      print $num.' ';
   }

Og der skrives så i browseren:
-1 17 -1 213 -1 117 -1 169 -1 5 -1 175 -1 117 -1 72 ... osv.


--
Bertel
http://bertel.lundhansen.dk/   Fiduso: http://fiduso.dk/

 
 
Jacob Atzen (05-07-2005)
Kommentar
Fra : Jacob Atzen


Dato : 05-07-05 15:58

On 2005-07-05, Bertel Lund Hansen <nospamfilius@lundhansen.dk> wrote:
> Hvorfor returnerer funktionen contains() to værdier?

Det gør den heller ikke. Jeg gætter på det er $sexes, der indeholder
noget du ikke har styr på.

> class Sex {
....

>    function contains ($name) {
>       foreach ($this->fornavne as $nr => $fornavn)
>          if ($name==$fornavn->navn) return $nr;
>       return -1;
>    }
....

> Jeg kalder den i følgende stump:
>
>    $name=$temp->fornavn;
>    foreach ($sexes as $s => $sex) {
>       $num=$sex->contains($name);
>       print $num.' ';
>    }
>
> Og der skrives så i browseren:
> -1 17 -1 213 -1 117 -1 169 -1 5 -1 175 -1 117 -1 72 ... osv.

Du udskriver jo et mellemrum efter hvert $num, og der er mellemrum
imellem hvert tal, altså bliver din foreach() løkke gennemløbet dobbelt
så mange gange som du tror.

--
Med venlig hilsen
- Jacob Atzen

Bertel Lund Hansen (05-07-2005)
Kommentar
Fra : Bertel Lund Hansen


Dato : 05-07-05 18:09

Jacob Atzen skrev:

> Du udskriver jo et mellemrum efter hvert $num, og der er mellemrum
> imellem hvert tal, altså bliver din foreach() løkke gennemløbet dobbelt
> så mange gange som du tror.

Jeg lavede følgende ændring hvor counter blev erklæret:

   function contains ($name) {
      ++$this->counter;
print "Counter: $this->counter ";
      foreach ($this->fornavne as $nr => $fornavn)
         if ($name==$fornavn->navn) return $nr;
      return -1;
   }

Det giver så:
Counter: 1 -1 Counter: 1 17 Counter: 1 -1 Counter: 1 213 Counter:
1 -1 Counter: 1 117 Counter: 1 -1 Counter: 1 169 Counter: 1 -1
Counter: 1 5 Counter: 1 -1 Counter: 1 175 Counter: 1 -1 Counter:
1 117 ...

Nu undrer det mig så også at tælleren ikke tæller op.

--
Bertel
http://bertel.lundhansen.dk/   Fiduso: http://fiduso.dk/

Jacob Atzen (05-07-2005)
Kommentar
Fra : Jacob Atzen


Dato : 05-07-05 18:32

On 2005-07-05, Bertel Lund Hansen <nospamfilius@lundhansen.dk> wrote:
> Jacob Atzen skrev:
>
>> Du udskriver jo et mellemrum efter hvert $num, og der er mellemrum
>> imellem hvert tal, altså bliver din foreach() løkke gennemløbet dobbelt
>> så mange gange som du tror.
>
> Jeg lavede følgende ændring hvor counter blev erklæret:
>
>    function contains ($name) {
>       ++$this->counter;
> print "Counter: $this->counter ";
>       foreach ($this->fornavne as $nr => $fornavn)
>          if ($name==$fornavn->navn) return $nr;
>       return -1;
>    }
>
> Det giver så:
> Counter: 1 -1 Counter: 1 17 Counter: 1 -1 Counter: 1 213 Counter:
> 1 -1 Counter: 1 117 Counter: 1 -1 Counter: 1 169 Counter: 1 -1
> Counter: 1 5 Counter: 1 -1 Counter: 1 175 Counter: 1 -1 Counter:
> 1 117 ...
>
> Nu undrer det mig så også at tælleren ikke tæller op.

Kan du poste et kørende kodeeksempel, der viser problemet, så skal jeg
tage et kig på det? Gerne på www.pastebin.com eller lignende.

Med kørende kodeeksempel mener jeg noget, som hvis jeg lægger det i en
fil og kører det igennem PHP fortolkeren viser mig det output du skriver
her.

--
Med venlig hilsen
- Jacob Atzen

Bertel Lund Hansen (05-07-2005)
Kommentar
Fra : Bertel Lund Hansen


Dato : 05-07-05 19:39

Jacob Atzen skrev:

> Kan du poste et kørende kodeeksempel, der viser problemet, så skal jeg
> tage et kig på det? Gerne på www.pastebin.com eller lignende.

Nu har jeg lagt et lille modeleksempel frem. Alle klasserne og
rutinerne er uændrede; det er kun datafilerne der er blevet
barberet:

Her kan man aktivere sin browser og se resultatet:
http://fiduso.dk/test/statistik.php

Her ligger PHP-koden i en tekstfil:
http://fiduso.dk/test/statistik.txt

De to reducerede datafiler:
http://fiduso.dk/test/medlem.dat
http://fiduso.dk/test/inifile.ini

PS. Hvis jeg inde i et højt kodeniveau har linjer som ikke er
indrykket, er det blot testlinjer som senere skal væk.

--
Bertel
http://bertel.lundhansen.dk/   Fiduso: http://fiduso.dk/

Jacob Atzen (05-07-2005)
Kommentar
Fra : Jacob Atzen


Dato : 05-07-05 20:30

On 2005-07-05, Bertel Lund Hansen <nospamfilius@lundhansen.dk> wrote:
> Nu har jeg lagt et lille modeleksempel frem. Alle klasserne og
> rutinerne er uændrede; det er kun datafilerne der er blevet
> barberet:
>
> Her kan man aktivere sin browser og se resultatet:
> http://fiduso.dk/test/statistik.php
>
> Her ligger PHP-koden i en tekstfil:
> http://fiduso.dk/test/statistik.txt
>
> De to reducerede datafiler:
> http://fiduso.dk/test/medlem.dat
> http://fiduso.dk/test/inifile.ini

Problemet ligger i din måde at bruge objekter på. I PHP4 er
standardmåden at håndtere objekter på med kopiering. Jeg kan se i koden,
at du er opmærksom på at videregive en del ting med referencer, så jeg
antager du har styr på forskellen på kopier og referencer.

I det aktuelle eksempel går det galt omkring linie 204:

foreach ($sexes as $s => $sex) {
$num=$sex->contains($name);

Løkken tager simpelthen kopier ud af arrayet fremfor referencer. En måde
at løse det på i det aktuelle eksempel er ved at tilgå array'et direkte:

foreach ($sexes as $s => $sex) {
$num=$sexes[$s]->contains($name);

Med denne konstruktion får du opdateret counteren som du ønsker.

Bemærk, at selve løkken principielt fungerer som den er kodet. De "to
returværdier" får du fordi du i hvert gennemløb laver et gennemløb for
begge sexes. Det ville nok være pænere at bruge en if-sætning i dette
tilfælde, da man må antage, at der ikke kommer flere køn på banen end
to.

Der er givetvis andre steder i din kode, hvor du vil være nødt til at
lave lignende krumspring, for at undgå at få kopier af dine objekter.

Derudover vil du muligvis have glæde af funktionen array_search(), jeg
bemærker, at du en del steder laver nogen foreach() ting med samme
effekt.

Endelig vil jeg råde dig til at skille dig af med dine globale variable.
Jeg kan se, at du en del steder bruger dem som konstanter, til dette
formål er define() normalt at foretrække, da du slipper for at erklære
noget globalt i dine funktioner og samtidig bliver det klarere, at det
er konstanter, du arbejder med.

--
Med venlig hilsen
- Jacob Atzen

Bertel Lund Hansen (05-07-2005)
Kommentar
Fra : Bertel Lund Hansen


Dato : 05-07-05 20:57

Jacob Atzen skrev:

> Problemet ligger i din måde at bruge objekter på. I PHP4 er
> standardmåden at håndtere objekter på med kopiering.

Aha!

> Løkken tager simpelthen kopier ud af arrayet fremfor referencer. En måde
> at løse det på i det aktuelle eksempel er ved at tilgå array'et direkte:

Okay.

> Bemærk, at selve løkken principielt fungerer som den er kodet. De "to
> returværdier" får du fordi du i hvert gennemløb laver et gennemløb for
> begge sexes.

Naturligvis - men jeg har en tendens til at overse sådanne simple
ting når frustrationen når tilstrækkelige højder.

> Det ville nok være pænere at bruge en if-sætning i dette
> tilfælde, da man må antage, at der ikke kommer flere køn på
> banen end to.

Det overvejede jeg, men besluttede mig for at lave den fleksible
løsning. Jeg vil muligvis oprette et tredje køn, nemlig "Ukendt".

> Der er givetvis andre steder i din kode, hvor du vil være nødt til at
> lave lignende krumspring, for at undgå at få kopier af dine objekter.

Ja, der er en del der skal revideres.

> Derudover vil du muligvis have glæde af funktionen array_search(), jeg
> bemærker, at du en del steder laver nogen foreach() ting med samme
> effekt.

Jeg har fundet array_search() i manualen, men jeg bruger
foreach() fordi arrayet indeholder objekter så jeg ikke kan tilgå
værdierne direkte. Alternativt skulle jeg oprette et temp-objekt
og array_searche på det, men det andet forekom enklere.

Jeg vil dog tjekke om jeg har overset nogle søgninger der kan
laves mere effektivt.

> til dette formål er define() normalt at foretrække,

Nå sådan!

Det var nogle gode fiduser jeg fik. Tak for dem.

--
Bertel
http://bertel.lundhansen.dk/   Fiduso: http://fiduso.dk/

Geert Lund (05-07-2005)
Kommentar
Fra : Geert Lund


Dato : 05-07-05 17:25

Bertel Lund Hansen wrote:

>    function contains ($name) {
>       foreach ($this->fornavne as $nr => $fornavn)
>          if ($name==$fornavn->navn) return $nr;
>       return -1;
>    }

> Og der skrives så i browseren:
> -1 17 -1 213 -1 117 -1 169 -1 5 -1 175 -1 117 -1 72 ... osv.

Du beder jo funktionen om at returnere noget 2 gange - hvis navnet - så
returner $nr og returner også -1 - hvis ikke navnet - returneres blot -1

Altså return -1 køres jo uanset om der findes noget eller ej - så vidt
jeg kan se...

--
Mvh.
Geert Lund


Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408929
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste