login  Naam:   Wachtwoord: 
Registreer je!
 Forum

Variabele uit een class dynamisch opvragen

Offline Rik - 26/06/2007 19:40
Avatar van RikGouden medailleGouden medaille

Crew algemeen
Hoi Sima's! 
Voor mijn eigen frameworkje ben ik een Core class aan het maken die classen kan laden. Heel simpel ziet dat er zo uit:
  1. <?php
  2. class Core {
  3. function loadClass($name) {
  4. if ($name::$makeInstance === true) {
  5. return new $name;
  6. } else {
  7. return true;
  8. }
  9. }
  10. }?>


Het is de bedoeling dat er een object van de te laden class wordt aangemaakt. Maar bij abstracte classen kan dat niet, daar moet je een object van een van de childklassen maken. Dat is op zich geen probleem, maar wel als ik moet checken of de class die ik ga laden abstract of een interface is. Volgens mij bestaat er geen manier om het type van de class op te vragen. Nu dacht ik het op te lossen door in classen waar geen object van mag worden gemaakt een variabele te setten die door de core class wordt gedetecteerd:
  1. <?php
  2. abstract class Database {
  3. static $makeInstance = false;
  4. }?>


Maar ik heb problemen om die variabele op te vragen... Database::$makeInstance werkt, maar dat heeft geen nut omdat die class loader dynamisch moet zijn. $name::$makeInstance geeft een error ("Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM") dus dat werkt niet. property_exists($name, 'makeInstance') geeft wel of makeInstance bestaat, maar dan weet ik nog steeds niet of het op true of false staat. Ik kan ook alle variabelen van de class opvragen met get_class_vars($name), maar dat is natuurlijk niet echt efficiënt.

Als laatste dacht ik nog aan eval('return ' . $name . '::$makeInstance;'), dat werkt wel, maar dat lijkt me ook een beetje omslachtig... Weet iemand hier een betere oplossing? Hoe zouden jullie dit doen?

4 antwoorden

Gesponsorde links
Offline Stijn - 26/06/2007 20:14
Avatar van Stijn PHP expert Waar is je include Zolang je geen codes include kan je geen instanties maken van je class.

Ik zou werken met een constante die je boven de class plaatst.
  1. define('CREATE_INSTANCE' , true);
Offline Rik - 26/06/2007 20:31
Avatar van Rik Gouden medailleGouden medaille

Crew algemeen
Klopt, de include staat er niet bij omdat dat nu toch al werkt. Om dit te testen had ik deze kleine stukkies code los in een bestand gezet dus de includes zijn daar sowieso niet nodig.

Jouw idee met een constante is leuk, maar als je voor elke class zo'n constante moet maken krijg je 'constant CREATE_INSTANCE already defined'. Dat is natuurlijk wel op te lossen door er
  1. define('DATABASE_CREATE_INSTANCE', true);
van te maken en dan
  1. constant(strtoupper($name) . '_CREATE_INSTANCE');
te gebruiken! 

Dat is maar iets minder omslachtig dan met de eval, ik zal eens kijken wat het makkelijkste gaat werken.
Offline marten - 26/06/2007 22:30
Avatar van marten Beheerder Je kan toch met PHP.net: class_implements kijken of de class interfaces bevat. Wanneer deze een array terug geeft weet je dat het zo is. Wanneer dit niet het geval is en een false terug geeft weet je dat de class geen interface bevat.
Offline Rik - 27/06/2007 16:57
Avatar van Rik Gouden medailleGouden medaille

Crew algemeen
Daar heb ik ook niet zo veel aan omdat ik eerst de hoofdclass in laadt en daarna pas eventuele subclassen. Zo kan ik dan nog niet checken of de hoofdclass een interface is... Bovendien werkt dat ook niet voor abstracte klassen. 
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.21s