[PHP] Éen grote globale variable

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Counter-Strike
  • Registratie: Maart 2000
  • Niet online

Counter-Strike

Maar ik speel het niet!

Topicstarter
Prettige kerstdagen wensen wordt niet echt op prijs gesteld dus dat doen we dan maar niet ;)

Ik heb het volgende stukje code
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
class class1 {
    var $arrayThingie = array();

   function class1Functie1($var) {
        array_push($this->arrayThingie, $var);
   }
   
   function class1Functie2() {
        print_r($this->arrayThingie);
   }
}

class class2{
   var $ref_to_class = NULL;

   function class2(&$reference){
        $this->ref_to_class=$reference;
   }

  function class2Functie2($var){
        $val = $this->ref_to_class->class1Functie1($var);
        return $val;
   }
}

$obj1 = new class1;
$obj2 = new class2($obj1);

$var=5;
$obj2->class2Functie2($var);        /* Hier gooien we
'5' naar class2. Class2 geeft 5 door aan functie class1Functie1
van class1 en deze stopt de waarde 5 in $arrayThingie */
$obj1->class1Functie2();            /* Print via
CLASS1 de (net gevulde) $arrayThingie */


Hierbij is het de bedoeling dat de array $arrayThingie wordt gevuld met waardes.
Nu kunnen deze waardes, zoals je in het scriptje kunt zien ook van andere classes komen. Wat is nu het probleem? Wanneer je een waarde aan deze array toevoegd via een andere class dan heb je deze in de 'main' class niet meer tot je beschikking. De array blijft dus leeg. De regel
PHP:
1
$obj1->class1Functie2();

geeft dus als output:
code:
1
Array()


De bedoeling is dat er ongeacht van waar deze array gevuld wordt altijd de waardes die ingevoerd zijn beschikbaar zijn.

Ik hoop dat jullie hier een oplossing voor weten. Ik zit er al een tijdje mee te prusten maar het wil niet echt lukken.

PS: dit stukje code heb ik als voorbeeld gegeven om jullie niet op te zadelen met andere niet relevante code. Voor een beter beeld: Class1 is in werkelijkheid een error handler. Class2 zou bijvoorbeeld een MySQL of template class kunnen zijn. Alle foutmeldingen die worden gegenereerd moeten in deze array komen en aan het eind worden gepresenteerd.

edit:
Zo, even ervoor gezorgd dat de layout niet zo vernaggeld wordt :)

[ Voor 10% gewijzigd door Counter-Strike op 25-12-2002 22:26 ]

Dit is het einde van deze mededeling. De mogelijkheid tot reageren is aanwezig!


Acties:
  • 0 Henk 'm!

  • eNaSnI
  • Registratie: November 2001
  • Niet online
Dus een soort sessie- of applicatie-variabele (PHP ken ik niet en ASP een beetje) ?

Wie zoekt, zal vinden http://www.google.com


Acties:
  • 0 Henk 'm!

Verwijderd

global $arrayThingie ?

Maar als het een puur een error handler moet zijn waarom dan zo'n ingewikkelde constructie?

Het is dan toch makkelijker om gewoon 1 error handling class te maken en die dan door de abdere scripts te vullen en dan in diezelfde class een functie te maken die bijv dumpError() heet?

*denkt graag simpel, want dat houd het leesbaar :-)*

Acties:
  • 0 Henk 'm!

Verwijderd

met een session variabele moet het lukken.
Je kan een hele object in zo'n variabele stoppen. En elke keer kan je deze weer terugvragen (en bewerken).

PHP:
1
2
3
4
5
6
7
8
<?
session_start();
if (!session_is_registered('obj1')) {
    session_register("obj1");
    $obj1 = new class1;
}

?>

Denkt dat je dit bedoelt...

[ Voor 7% gewijzigd door Verwijderd op 25-12-2002 23:01 ]


Acties:
  • 0 Henk 'm!

  • Counter-Strike
  • Registratie: Maart 2000
  • Niet online

Counter-Strike

Maar ik speel het niet!

Topicstarter
Verwijderd schreef op 25 december 2002 @ 22:53:
global $arrayThingie ?

Maar als het een puur een error handler moet zijn waarom dan zo'n ingewikkelde constructie?

Het is dan toch makkelijker om gewoon 1 error handling class te maken en die dan door de abdere scripts te vullen en dan in diezelfde class een functie te maken die bijv dumpError() heet?

*denkt graag simpel, want dat houd het leesbaar :-)*
Dit doe ik in principe al hoor. Er bestaat al een functie getErrors (in de error handler class (a.k.a. class1)) die die array uitleest en dat vervolgens presenteerd. Probleem is alleen dat als er bijvoorbeeld tijdens het connecten naar LDAP (via een php class) iets fout gaat en ik stuur een foutmelding naar de error handler dat deze niet bewaard blijft. Nogmaals een error plaatsen in de array vanuit dezelfde class levert gewoon een 2e resultaat op. Maar wanneer er in een andere class, bijvoorbeeld de template class een error wordt gegenereerd dan zijn de andere ingevoerde errors van de LDAP class weg.

Sterker nog. Wanneer je vanuit een normaal script (dus niet per sé via een class) $arrayThingie probeert op te halen dan zijn de gegenereerde errors ook niet aanwezig. (lees: array is leeg).

Simpel gezegd:

class2 ---> fout! --> stuur melding naar $arrayThingie in class1.
class2 ---> nog een fout! --> stuur melding naar $arrayThingie in class1.
Op dit moment zijn er gewoon twee records aanwezig in de array, let wel, wanneer je de array opvraagt vanuit class2!

class2 ---> fout! --> stuur melding naar $arrayThingie in class1.
class1 ---> fout! --> stuur melding naar $arrayThingie in class1.
Wanneer je nu vanuit class1 $arrayThingie uitleest zie je ALLEEN de error die gegenereerd wordt in class1!

class2 ---> fout! --> stuur melding naar $arrayThingie in class1.
class1 ---> fout! --> stuur melding naar $arrayThingie in class1.
Wanneer je nu vanuit een niet-class $arrayThingie uitleest zie je GEEN errors die gegenereerd werden!

In alle drie de gevallen moet het mogelijk zijn om $arrayThingie volledig uit te lezen.

Zo al wat duidelijker? Wat bedoel je nu precies met global()? dat kan ik namelijk niet helemaal plaatsen :)

Dit is het einde van deze mededeling. De mogelijkheid tot reageren is aanwezig!


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

Nee, het gaat hier niet over pagina overgangen :)

Mijn eerste gedachte was dat het gewoon het type afdrukken was. Dat gaat namelijk vaak fout. Maar ik zag dat je print_r gebruikte, dus daar zou het niet aan kunnen liggen. Wat gebeurt er trouwens waneer je die functie niet via de 2e class aanroept, maar gewoon rechtstreeks? Het kan best zijn dat php je tegen een php bug aangelopen bent :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

De oplossing die je op dit moment gebruikt, is veel netter dan global (Maar dan moet ie natuurlijk wel werken.

Na nog ff gekeken te hebben denk ik dat het misgaat bij de constructor van class2. Daar zul je waarschijnlijk ook ff expliciet aan moeten geven dat je de membervar byref wil toekennen. Anders kun je ook nog ff proberen om niet alleen bij de functie definitie, maar ook bij de functie aanroep het object byref mee te geven? (dus daar ook met het & teken)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Counter-Strike
  • Registratie: Maart 2000
  • Niet online

Counter-Strike

Maar ik speel het niet!

Topicstarter
Gaat ie:

Met deze code:
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
class class1 {
    var $arrayThingie = array();

   function class1Functie1($var) {
        array_push($this->arrayThingie, $var);
        global $arrayThingie;
   }
   
   function class1Functie2() {
        print_r($this->arrayThingie);
   }
}

class class2{
   var $ref_to_class = NULL;

   function class2(&$reference){
        $this->ref_to_class=$reference;
   }

  function class2Functie2($var){
        $val = $this->ref_to_class->class1Functie1($var);
        return $val;
   }
}

$obj1 = new class1;
$obj2 = new class2($obj1);


We houden alles bij 1 array:
PHP:
1
2
3
4
$obj1->class1Functie1('error 1');
$obj1->class1Functie1('error 2');
$obj1->class1Functie1('error 3');
$obj1->class1Functie2();

geeft

code:
1
2
3
4
5
6
Array
(
    [0] => error 1
    [1] => error 2
    [2] => error 3
)

das goed! :)

Hier niet!
PHP:
1
2
3
4
$obj1->class1Functie1('error 1');
$obj2->class2Functie2('error 2');
$obj2->class2Functie2('error 3');
$obj1->class1Functie2();

code:
1
2
3
4
Array
(
    [0] => error 1
)

Fout! :( Hij pakt hier enkel de eerste en niet de errors die er door de 2e class zijn ingestopt.

Bovenstaande andersom:
PHP:
1
2
3
4
$obj2->class2Functie2('error 1');
$obj1->class1Functie1('error 2');
$obj1->class1Functie1('error 3');
$obj1->class1Functie2();


code:
1
2
3
4
5
Array
(
    [0] => error 2
    [1] => error 3
)

Fout :(

Deze voorbeeldjes zijn gegeven van buiten de classes. Het gaat ook fout wanneer je de opdracht vanuit de classes zelf geeft, bijvoorbeeld:

PHP:
1
2
$this->ref_to_class->class1Functie1('error 2');
$this->ref_to_class->class1Functie1('error 3');

vanuit class2.
Wie snapt het nog? :)

[ Voor 27% gewijzigd door Counter-Strike op 25-12-2002 23:38 ]

Dit is het einde van deze mededeling. De mogelijkheid tot reageren is aanwezig!


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

Zoals ik al zei.
PHP:
1
2
3
   function class2(&$reference){ 
        $this->ref_to_class=$reference; 
   }

Maak ook deze toekenning eens byref ipv byvalue ;)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Counter-Strike
  • Registratie: Maart 2000
  • Niet online

Counter-Strike

Maar ik speel het niet!

Topicstarter
PHP:
1
2
3
   function class2(&$reference){
        $this->ref_to_class=&$reference;
   }


Woei!! :) Werkt!
Nu nog even begrijpen hoe het in elkaar steekt. Daar leren we per slot van rekening van :P

Goed:
Door middel van:
PHP:
1
function class2(&reference) ...

refereer je naar het object dat je daaraan toe kent. In dit geval dus de error handler class (a.k.a. class1). Vervolgens slaan we die referentie op in de variable $ref_to_class. Deze kunnen we nu dus gebruiken om te praten met class1. Right?

Ik snap nu alleen nog niet wat die 2e referentie doet :?
PHP:
1
$this->ref_to_class=&$reference;


Is dit misschien omdat hij nu niet de reverentie naar het object (de class), maar gewoon de class kopieert? Dat zou dan inderdaad verklaren waarom hij de boel niet toevoegd maar alles opnieuw maakt. (lees: alles op een andere plek in het geheugen opnieuw specificeren) Hij maakt immers een kopie!

Klopt dit?

[ Voor 8% gewijzigd door Counter-Strike op 26-12-2002 00:37 ]

Dit is het einde van deze mededeling. De mogelijkheid tot reageren is aanwezig!


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
yep :) hoewel je reeds het argument als een reference doorgeeft moet je hem nogmaals als reference 'casten' anders doet PHP a copy: MAW een ander object... en nog effe zeggen dat je steeds $foobar = &new Class(); moet doen anders maakt ie er twee (voor dezelfde reden... want new Class = reference maar als je dan geen reference copy maakt gaat PHP dat beschouwen als een echte copy...). Dus als je Pointers wil toepassen altijd & gebruiken (oh en als je ooit een oude reference overschrijft met een nieuwe moet je die unsetten (of unlinken) ih geval hierboven dus unset($foobar); $foobar = &new Class2(). Misschien kunnen die tips ergens in een FAQ hier ofzo?...

  • Counter-Strike
  • Registratie: Maart 2000
  • Niet online

Counter-Strike

Maar ik speel het niet!

Topicstarter
hobbit_be schreef op 26 December 2002 @ 01:33:
yep :) hoewel je reeds het argument als een reference doorgeeft moet je hem nogmaals als reference 'casten' anders doet PHP a copy: MAW een ander object... en nog effe zeggen dat je steeds $foobar = &new Class(); moet doen anders maakt ie er twee (voor dezelfde reden... want new Class = reference maar als je dan geen reference copy maakt gaat PHP dat beschouwen als een echte copy...). Dus als je Pointers wil toepassen altijd & gebruiken (oh en als je ooit een oude reference overschrijft met een nieuwe moet je die unsetten (of unlinken) ih geval hierboven dus unset($foobar); $foobar = &new Class2(). Misschien kunnen die tips ergens in een FAQ hier ofzo?...
Zou je het vet gedrukte nog iets duidelijker willen uitleggen? Het drinkt nog niet helemaal door :P

Bedankt :)

Dit is het einde van deze mededeling. De mogelijkheid tot reageren is aanwezig!


Verwijderd

Counter-Strike schreef op 26 December 2002 @ 11:39:
[...]


Zou je het vet gedrukte nog iets duidelijker willen uitleggen? Het drinkt nog niet helemaal door :P

Bedankt :)
Ik denk dat je dan best dit eens leest ;)
... "new" does not return a reference by default, instead it returns a copy.

Note: There is no performance loss (since PHP 4 and up use reference counting) returning copies instead of references. On the contrary it is most often better to simply work with copies instead of references, because creating references takes some time where creating copies virtually takes no time (unless none of them is a large array or object and one of them gets changed and the other(s) one(s) subsequently, then it would be wise to use references to change them all concurrently).
Dus

PHP:
1
2
$bar1 = new Foo('set in constructor');
$bar2 =& new Foo('set in constructor');


In $bar1 zit een copy van Foo class terwijl in $bar2 een reference naar Foo class zit.

[ Voor 6% gewijzigd door Verwijderd op 26-12-2002 15:45 . Reden: code tag aangepast ]


  • Counter-Strike
  • Registratie: Maart 2000
  • Niet online

Counter-Strike

Maar ik speel het niet!

Topicstarter
Verwijderd schreef op 26 december 2002 @ 14:02:
[...]


Ik denk dat je dan best dit eens leest ;)


[...]


Dus

PHP:
1
2
$bar1 = new Foo('set in constructor');
$bar2 =& new Foo('set in constructor');


In $bar1 zit een copy van Foo class terwijl in $bar2 een reference naar Foo class zit.
OK, ik begrijp hem nu helemaal! Toch maar eens die oop sectie in de manual rustig doornemen. Staan toch meer hints in dan je verwacht!

Ik denk dat een bedankje aan iedereen die mij heeft geholpen wel op zijn plaats is!

:) Bedankt :)

Dit is het einde van deze mededeling. De mogelijkheid tot reageren is aanwezig!

Pagina: 1