#1 před rokem

pete
Člen
Registrovaný: 22. 10. 2009
Příspěvky: 25

Enum v php

caute,
iba by som sa chcel spytat ze ako riesite Enum v php.
Ide mi o to aby som v metode mohol specifikovat presne ake hodnoty (argumenty) tam mozu byt vlozene (vyvarovat sa chybam, zobrazit napovedu v IDE atd.)
Ja som sa inspiroval Javou kde enum je ako keby trieda, daju sa tam pridavat metody, instancne premene atd avsak vytvaranie instanci je obmedzene na vami specifikovane hodnoty.
Toto je moj priklad (je to z paypal ked sa specifikuje environment)

<?php
/**
 * paypal environment - live, sandbox or beta sandbox
 */
final class Environment {

    /**
     * Holds instances for lazy initialization.
     *
     * @var array<Environemnt>
     */
    private static $instances = array();

    /**
     *
     * @var string id of the enum, name of the method that returned instance
     */
    private $name;

    /**
     *
     * @var string part url representing environment
     */
    private $value;

    /** @param string $value environment part of the url */
    private function __construct($name, $value) {

        $this->name = $name;
        $this->value = $value;
    }

    /**
     * live environment
     *
     * @return self
     */
    public static function LIVE() {

        $name = 'LIVE';
        $value = '';
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = new self($name, $value);
        }
        return self::$instances[$name];
    }

    /**
     * test environment
     *
     * @return self
     */
    public static function SANDBOX() {

        $name = 'SANDBOX.';
        $value = 'sandbox.';
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = new self($name, $value);
        }
        return self::$instances[$name];
    }

    /**
     * beta test environment
     *
     * @return self
     */
    public static function BETA_SANDBOX() {

        $name = 'BETA_SANDBOX.';
        $value = 'beta-sandbox.';
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = new self($name, $value);
        }
        return self::$instances[$name];
    }

    /**
     * Return url where you send request, this changes according to the
     * environment set.
     *
     * @return string   url string where to send request
     */
    public function getEnvironmentPartURL() {
        return $this->value;
    }

    public function __toString() {
        return $this->name;
    }

    private function __clone() {}
}
?>

Mozno su tam nejake chybicky, este som to netestoval, ale na ilustraciu to staci.
Da sa to pouzit v metode takto:

<?php
public function setEnvironment(Environment $environment) {
    // ...
}
?>

volanie tejto metody:

<?php
$pp->setEnvironment(Environment::LIVE());
?>

toto bol samozrejme specificky priklad, kde sa daju pridavat metody a argumenty ktore sa posielaju do konstruktora, klasicke enum by vyzeralo takto:

<?php
/**
 * paypal environment - live, sandbox or beta sandbox
 */
final class Environment {

    /**
     * Holds instances for lazy initialization.
     *
     * @var array<Environemnt>
     */
    private static $instances = array();

    /**
     *
     * @var string enum id - name of the static method that returned instance
     */
    private $name;

    private function __construct($name) {
        $this->name = $name;
    }

    /**
     * live environment
     *
     * @return self
     */
    public static function LIVE() {

        $name = 'LIVE';
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = new self($name);
        }
        return self::$instances[$name];
    }

    /**
     * test environment
     *
     * @return self
     */
    public static function SANDBOX() {

        $name = 'SANDBOX';
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = new self($name);
        }
        return self::$instances[$name];
    }

    /**
     * beta test environment
     *
     * @return self
     */
    public static function BETA_SANDBOX() {

        $name = 'BETA_SANDBOX';
        if (!isset(self::$instances[$name])) {
            self::$instances[$name] = new self($name);
        }
        return self::$instances[$name];
    }

    public function __toString() {
        return $this->name;
    }

    private function __clone() {}
}
?>

pouzitie:

<?php
$environment = Environment::SANDBOX();
echo $environment;
?>

Editoval pete (28. 5. 2010 18:28)

 

#2 před rokem

phx
Moderator
Registrovaný: 17. 4. 2008
Příspěvky: 878

Re: Enum v php

A nestacilo by ti pole konstant? Hold by se programator musel toho, ze pridava pouze konstanty a ne nejake svoje texty.

Neco jako

class MojeEnum {
        const FOO = 'foo';
        const BAR = 'bar';

        private $data = array();

        public function add($value) {
                $this->data[] = $value;
        }
}

 

#3 před rokem

pete
Člen
Registrovaný: 22. 10. 2009
Příspěvky: 25

Re: Enum v php

No ako som uz spomenul, ze by som to chcel type safe, v tvojom pripade by som nemohol urobit nieco taketo:

<?php
class Test {
    public function setEnum(MojeEnum $enum) {
        // ...
    }
}

$test = new Test();
/* toto nefunguje */
$test->setEnum(MojeEnum::FOO); // vkladam string a nie MojeEnum, nieje type safe
?>

Takze ako vidis ja by som nemohol ovplyvnit aky argument sa bude vkladat do mojej metody v classe Test. Ak vydavas kniznicu tak je to dost dolezite (menej chyb a uzivatel hned vie co ma vlozit ako argument), plus nemusis kontrolovat ake hodnoty vklada. Ak by sa hodnota tej konstanty zmenila tak musis zmenit validaciu v kazdej metode kde to bolo pouzite ako argument atd.

Dalej moc dobre nerozumiem tej metode:

<?php
public function add($value) {
    $this->data[] = $value;
}
?>

Ked pridas hodnotu, tak to budu zdielat vsetky instancie, a nie iba FOO alebo iba BAR.

Editoval pete (29. 5. 2010 17:54)

 

Zápatí