Ola,

Ik heb een vraagje... ik heb een class waarin ik de naam van een constante kan ophalen. Nu had ik in 1e instantie een method waarbij telkens 2 controles plaatsvinden, en daar heb ik nu een method van gemaakt met een extra overkoepelende controle. Dit laatste heb ik gedaan om, indien de method meer dan 1x wordt aangeroepen, geen dubbele controles te hoeven uitvoeren. Ik ben benieuwd welke versie jullie beter vinden en waarom. Hieronder even 2 voorbeeldjes van hoe het ongeveer werkt.

Voorbeeld 1:

<?php
class Language {

const DUTCH = 1;

static private $languages_values;

static public function getConstName($value) {
if (!isset(self::$languages_values)) { // controle 1
$ref_class = new \ReflectionClass(self::class);
self::$languages_values = array_flip($ref_class->getConstants());
}
if (!isset(self::$languages_values[$value])) { // controle 2
thow new \Exception('de value bestaat niet!');
}
return self::$languages_values[$value];
}

}
?>
In de opzet hierboven wordt telkens als je getConstName() aanroept eerst gecontroleerd of de property languages_values wel is geset, en daarna wordt gecontroleerd of de value in die array voorkomt.

Nu heb ik er dit van gemaakt:

Voorbeeld 2:

<?php
class Language {

const DUTCH = 1;

static private $languages_values;

static public function getConstName($value) {
if (!isset(self::$languages_values[$value])) { // extra controle
if (!isset(self::$languages_values)) {
$ref_class = new \ReflectionClass(self::class);
self::$languages_values = array_flip($ref_class->getConstants());
}
if (!isset(self::$languages_values[$value])) {
thow new \Exception('de value bestaat niet!');
}
}
return self::$languages_values[$value];
}

}
?>
Ik heb er dus een extra if-statement omheen gezet, die direct al kijkt of de value bestaat. Wat vinden jullie van deze aanpak?
Dit ziet er netter en begrijpelijker uit naar mijn idee:

http://3v4l.org/Bl4TO
<?php

namespace Ozzie;

use Exception;
use ReflectionClass;

class Language {

const DUTCH = 1;

private static $languages_values;

public static function getConstName($value) {
if (isset(self::$languages_values[$value])) {
return self::$languages_values[$value];
}

throw new Exception('de value bestaat niet!');
}

public static function init() {
static $initialized = false;

if ( ! $initialized) {
$ref_class = new ReflectionClass(self::class);
self::$languages_values = array_flip($ref_class->getConstants());

$initialized = true;
}
}

}

// ja, dit zet je in het zelfde bestand
Language::init();

// nee, dit dan weer niet niet
echo Language::getConstName(1), Language::getConstName(42);

// phphulp only:
?>
Dos, dan moet je dus telkens voordat je getConstNamn uitovert een init() uitvoeren?

Ik snap de init functie niet helemaal. Eerst zet je $initialized op false, en vervolgens controleer je of ie niet false is?
"Dos, dan moet je dus telkens voordat je getConstNamn uitovert een init() uitvoeren?"
Nee, maar een keer. En dan doe je in het bestand waar je de Language classe defineerd. Op die manier is Language::init() altijd uitgevoerd op het moment dat je Language::getConstName() wilt gebruiken.

"Eerst zet je $initialized op false, en vervolgens controleer je of ie niet false is?"
Ik zet initialized op false en kijk dan of ie niet true is.

http://www.phphulp.nl/php/forum/topic/name-id-description/94779/#680318 mocht je static $initialized niet snappen.
Ik snap die static... maar je zet 'm nu toch iedere keer op false?

Toevoeging op 05/05/2014 19:28:19:

>> En dan doe je in het bestand waar je de Language classe defineerd.

Wat bedoel je hiermee? Ik definieer niks, want ik gebruik een autoloader :-s
...

Ik heb het niet over het gebruik van \define()...

Ik heb het over
<?

class foo {
// dit is een class definition
}

// zet dit in het zelfde bestand, op die manier is het altijd uitgevoegd wanneer foo beschikbaar is
foo::init();

?>

"Ik snap die static... maar je zet 'm nu toch iedere keer op false?"
Als dat zo was zou deze code 42 keer '1' moeten printen: http://3v4l.org/13gHJ
Maar we zijn weer lekker bezig.

Je gaat eerst constanten met een waarde definiëren, en daarna ga je de naam van de constante opvragen aan de hand van die waarde.

Jij bent zo van de real-time voorbeelden:
Ik heb een motor met een bepaald soort klep, ik ga eerst de motor uit elkaar halen om de naam van die zuigerklep te achterhalen.

In jouw voorbeeld met Language, moet je elke keer als je een taal wilt toevoegen je class aanpassen.
Als dat OOP is, ben ik Attila de Hun.
@Dos:

>> // zet dit in het zelfde bestand, op die manier is het altijd uitgevoegd wanneer foo beschikbaar is

Ah, op die fiets! Dat is inderdaad een goede truc!!! :)

* EDIT: kan dit ook bij een abstract class?

>> Als dat zo was zou deze code 42 keer '1' moeten printen

Oké... dan snap ik dus niet hoe die static werkt blijkbaar. Waarom verandert die niet van waarde? :-s

@Atilla de Hun:

>> In jouw voorbeeld met Language, moet je elke keer als je een taal wilt toevoegen je class aanpassen.

Kun je uitleggen wat je hiermee bedoelt? Hoezo moet ik m'n class aanpassen?

<?php

class Language {

const DUTCH = 1;
const WARTAAL = 0;

}
?>

Nu willen we English erbij, dan gaat jouw methode niet werken, want die gooit een Exception.
Correct. Dan zal je die moeten toevoegen. Maar dat moet je toch altijd? Of wil jij iedere language kunnen setten ofzo? Dus dat je dit kunt doen? $language->set('DUTCH', 1) Bedoel je dat? Leg anders even uit hoe het volgens jou wél zou moeten. Daar ben ik wel benieuwd naar.
Ik denk dat je het begrip constante verkeerd interpreteert.

Gegevens die dynamisch (kunnen) zijn sla je niet in de class zelf op, maar in een gegevensbestand.

Reageren