2

I am trying to understand how I can build a sort of knowledge tree/ontology using associative arrays and consts in PHP. The following example shows what I'm trying to do:

class Fruit {
    public static $TYPES = array("APPLE" => array("GREEN" => Apple::GREEN), array("RED" => Apple::RED)); 
}

class Apple {
    public static $GREEN = array("GRANNY_SMITH" => array("FLAVOUR" => array(Flavour::SHARP, Flavour::SWEET)), 
                                 "GOLDEN_DELICIOUS" => array("FLAVOUR" => array(Flavour::SWEET, Flavour::BLAND))); 

    public static $RED = array("RED_DELICIOUS" => array("FLAVOUR" => array(Flavour::SOUR, Flavour::SHARP)), 
                               "PAULA_RED" => array("FLAVOUR" => array(Flavour::SWEET, Flavour::SOUR)));  
}

class Flavour {
    const SHARP = "sharp";
    const SWEET = "sweet";
    const SOUR = "sour";
    const BLAND = "bland";
}

From this I want to be able to retrieve values something like:

$flavours = Fruit::TYPES["APPLE"]["GREEN"]["GOLDEN_DELICIOUS"];

So basically I am getting a list of flavours associated with Golden Delicious apples... Is there a better way to represent a static data tree like this in PHP? In Java I would use Enums...

6
  • You cannot initialize a constant with an array. So just create another class with 1 constant per value as you've done in class Flavour. Commented Aug 8, 2012 at 5:00
  • Ok so is there something like an immutable array mechanism that could work? Commented Aug 8, 2012 at 5:04
  • nope. Only constants are immutable in php Commented Aug 8, 2012 at 5:05
  • 1
    You can make it as private and add getter Commented Aug 8, 2012 at 5:05
  • Not true, you can create an immutable array in php Commented Aug 8, 2012 at 6:33

2 Answers 2

3

Answering the comment about an immutable array:

class ImmutableArray extends ArrayObject
{
    const ERROR = 'Immutable array!';

    public function __construct($input, $flags = 0, $iterator_class = 'ArrayIterator') {
        parent::__construct($input, $flags, $iterator_class);
    }

    public function __get($key) {
        return $this->offsetGet($key);
    }

    public function __isset($key) {
        return $this->offsetExists($key);
    }

    public function __set($key, $value) {
        throw new Exception(self::ERROR);
    }

    public function __unset($key) {
        throw new Exception(self::ERROR);
    }

    public function append($value) {
        throw new Exception(self::ERROR);
    }

    public function asort() {
        throw new Exception(self::ERROR);
    }

    public function ksort() {
        throw new Exception(self::ERROR);
    }

    public function natcasesort() {
        throw new Exception(self::ERROR);
    }

    public function natsort() {
        throw new Exception(self::ERROR);
    }

    public function offsetSet($key, $value) {
        throw new Exception(self::ERROR);
    }

    public function offsetUnset($key) {
        throw new Exception(self::ERROR);
    }

    public function uasort($cmp_function) {
        throw new Exception(self::ERROR);
    }

    public function uksort($cmp_function) {
        throw new Exception(self::ERROR);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Try and see $a = new ImmutableArray(array()); var_dump(is_array($a)); -- ArrayObject cannot completely replace arbitrary array
0

For anyone looking for an answer with modern PHP versions: since php 5.6 const arrays and complex initializations are implemented in PHP. See what's new in php 5.6

class Fruit {
    const TYPES = [
        "APPLE" => ["GREEN" => Apple::GREEN, "RED" => Apple::RED]
    ]; 
}

class Apple {
    const GREEN = [
        "GRANNY_SMITH" => ["FLAVOUR" => [Flavour::SHARP, Flavour::SWEET]], 
        "GOLDEN_DELICIOUS" => ["FLAVOUR" => [Flavour::SWEET, Flavour::BLAND]]
    ]; 

    const RED = [
        "RED_DELICIOUS" => ["FLAVOUR" => [Flavour::SOUR, Flavour::SHARP]], 
        "PAULA_RED" => ["FLAVOUR" => [Flavour::SWEET, Flavour::SOUR]]
    ];  
}

class Flavour {
    const SHARP = "sharp";
    const SWEET = "sweet";
    const SOUR = "sour";
    const BLAND = "bland";
}

var_dump(Fruit::TYPES["APPLE"]["GREEN"]["GOLDEN_DELICIOUS"]);

Above code will output (as expected):

array(1) { 'FLAVOUR' => array(2) { [0] => string(5) "sweet" 1 => string(5) "bland" } }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.