Arraywaarde uit andere class ophalen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mark PHP

Mark PHP

30/03/2008 22:30:00
Quote Anchor link
Ik loop al een tijdje tegen het volgende probleem aan: stel ik heb een class waar bv. een configuratie is opgeslagen in een array. In een andere klass wil ik één waarde van die array echo-en. Dat doe ik dus met $class->variabele['array-key']. Echter, PHP haalt dan eerst de $class->variabele (de complete array) op, voor de goede waarde bij de key te zoeken.

Dit kan tot geweldige performanceverlies leiden heb ik al gemerkt, dus er moet een manier zijn om dit te voorkomen. Nu kan het wel door een extra methode in te bouwen, bv. getConf($key), die in class X al de key pakt en returned, maar dat vind ik nogal een lelijke manier.

Als voorbeeldje:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class X {
  public $conf = array('name' => 'Agirre', 'age' => 19);

  //blabla
}

class Y {
  public function __construct() {
    $x = new X();
    echo $x->conf['name'];
    //hierboven wordt eerst $x->conf
    //opgehaald voordat de key 'name'
    //wordt gepakt.


  }
}

?>
Suggesties?
Gewijzigd op 01/01/1970 01:00:00 door Mark PHP
 
PHP hulp

PHP hulp

07/01/2025 16:49:33
 
Stien ss

stien ss

30/03/2008 22:40:00
Quote Anchor link
Wat je kan proberen is de SPL interface ArrayAccess te implementeren in je X class. Dan kan je gewoon echo $x['name']; doen en dan wordt denk ik niet heel de array opgehaald.

Waarom zou je niet getConf ($key) gebruiken, ik denk dat dat toch de beste oplossing is voor jou probleem.

Is het performanceverlies echt zo groot? Kan ik me bijna niet voorstellen.
 
Jurgen assaasas

Jurgen assaasas

30/03/2008 22:42:00
Quote Anchor link
Ik wist niet dat PHP dat deed, lijkt me ook vrij nutteloos je zou een variabel (mits public) gewoon aan moeten kunnen spreken op zijn key als het een array is zonder de key door te lopen.

zoals je zei dus, maar dit lijkt me logischer.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php

$classA
= new classA();

$classB = new classB($classA->var['id']);

?>


Dit lijkt mij de makkelijkste manier om een variabelen door te geven.
 
Mark PHP

Mark PHP

30/03/2008 22:45:00
Quote Anchor link
Ik zal er even over nadenken. Probleem is dat het goed mogelijk is om meerdere arrays te hebben, bv. configuratie en properties. Dan is ArrayAccess lastig.
Hetzelfde geldt eigenlijk voor zo'n aparte methode, aangezien het een Registry class is (en je dus eigenlijk niet weet wat voor variabelen er zijn opgeslagen).

Over het performance verlies, ik had eerst een class Countries, en daar zaten 200+ landen in zo'n array. Als je dan elke keer de hele array moet ophalen om één land weer te geven, kan het nogal lang duren om er bijvoorbeeld 25 weer te geven (halve seconde).

@Jurgen: gaat denk ik ook niet werken, stel ik moet 25 waarden hebben, dan wordt het wel een lang verhaal.
Gewijzigd op 01/01/1970 01:00:00 door Mark PHP
 
Jelmer -

Jelmer -

31/03/2008 14:07:00
Quote Anchor link
Volgens mij zit het probleem ergens anders. PHP is slim genoeg om niet zomaar een array te kopiëren. $x->conf[$i] is maar een heel klein beetje langzamer dan $a = &$x->conf; $a[$i]. Waarschijnlijk om de reden dat hij bij de eerste syntax eerst $x in het geheugen opzoekt, en dan pas de array. Bij de tweede is $a de array $x->conf.

Getest met een array van 100.000 strings van ongeveer 900 karakters per item. Met geen van beide manieren duurde het langer dan een tiende seconde om ieder element in de array op die manier te benaderen.

Weet je zeker dat je de array niet 25 keer opnieuw aanmaakt? (oplossing: static keyword gebruiken) Of dat je een bestand met de array 25 maal include?
 
Mark PHP

Mark PHP

31/03/2008 16:08:00
Quote Anchor link
Het zit als volgt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class Registry {
  private $store = array(
    config => array('host' => 'localhost')
  );


  //constructor etc.

  public function __get($key) {//$key geeft 'config'
    return isset($this->store[$key]) ? $this->store[$key] : false;
  }
}


class Retrieve {
  public function __construct() {
    $registry = new Registry();
    echo $registry->config['host'];
  }
}

?>
Doordat de magic __get 'config' teruggeeft, neem ik aan dat deze de hele array retourneerd.
Toen ik een getCountry() implementeerde in mijn Countries class, was het script namelijk veel en veel sneller.
Gewijzigd op 01/01/1970 01:00:00 door Mark PHP
 
Jelmer -

Jelmer -

31/03/2008 16:28:00
Quote Anchor link
Ja, geen wonder. Een return-value is normaal inderdaad een kopie. Je kan echter wel afdwingen dat hij gewoon een reference neemt, maar dan moet je wel oppassen dat je geen wijzigingen aan de variabele toepast. Die worden dan namelijk ook in het register doorgevoerd.

En nu ik dit test merk ik ook een merkwaardigheid in mijn versie van PHP. Ik gebruik hierbij jouw code, heb alleen de inhoud van Retrieve aangepast. Namelijk:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$registry
= new Registry();
$registry->config['host'] = 'Blaat';
var_dump($registry);
?>

verandert het register niet (zoals je zou verwachten). Echter, de volgende code verandert het register bij mij wel. Merk op dat ik $x verder niet eens gebruik.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
$registry
= new Registry();
$x = &$registry->config['host']; // let op deze
$registry->config['host'] = 'Blaat';
var_dump($registry);
?>

Deze code levert trouwens 2 notices op, "PHP Notice: Indirect modification of overloaded property Registry::$config has no effect" voor regel 3 & 4. Maar blijkbaar heeft het wel degelijk effect... De eerste code levert diezelfde waarschuwing ook op, maar daar klopt hij ook.
 
Mark PHP

Mark PHP

31/03/2008 17:20:00
Quote Anchor link
Mja oke ... een referentie wijst nog steeds naar de hele array, maar een referentie is maar 1 'ding'. Beter dan een volledig kopie, weet alleen niet of het makkelijker werkt.

EDIT: hmm geen idee hoe ik dit goed werkend moet krijgen.
Gewijzigd op 01/01/1970 01:00:00 door Mark PHP
 
Mark PHP

Mark PHP

02/04/2008 20:49:00
Quote Anchor link
Zou je een voorbeeld kunnen geven van een referentie waarbij geen kopie wordt gemaakt? Ik kom er namelijk niet uit en de pagina wordt steeds slomer...
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.