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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.