Hi Clint,

1) Point taken.

2) The use case can be solved with an object implementing ArrayAccess,
but not pragmatically, because then you need a class for *each*
bidirectional association. Let me give a short example:

Given the class Article with a bidirectional many-to-one relation to
Category and a bidirectional many-to-many relation to Tag, currently
you implement the following methods to manage these relations:

Article::setCategory($category);
Article::addTag($tag);

Category::addArticle($article); // calls $article->setCategory($category)

Tag::addArticle($article); // calls $article->addTag($tag)

(there are different ways to implement this, but usually at least one
side of the relation also calls the setter/adder on the other side)

You *cannot* implement the $articles collection in Category and Tag
using the same class ArticleCollection, because in one case
addArticle($article) calls setCategory($category), in the other
addTag($tag). In other words, ArticleCollection depends both on the
related class (Category, Tag) and the arity (setXxx() vs. addXxx()) of
the relation. Consequently, every relation needs a custom collection
class and you end up with the classes

Article
Category
Tag
ArticleTags
CategoryArticles
TagArticles

just for this simple example if following your approach.

With array accessors, this can be solved much more elegantly:

class Article {
    public $category {
        set();
        get();
    }

    public $tags {
        offsetSet();
        offsetGet();
    }
}

class Category {
    public $articles {
        offsetSet($offset, $article) {
            $this->_articles[$offset] = $article;
            $article->category = $this;
        }
        offsetGet();
    }
}

class Tag {
    public $articles {
        offsetSet($offset, $article) {
            $this->_articles[$offset] = $article;
            $article->tags[] = $this;
        }
        offsetGet();
    }
}

$article->category = $category;
$article->tags[] = $tag;

$category->articles[] = $article; // sets $article->category = $category

$tag->articles[] = $article; // adds $article->tags[] = $tag

(I know that this example has some flaws, like the automatic
offsetGet() or the missing $_articles field, but I guess you get my
point)

3) I don't know if many other languages allow overloading of the array
accessors at all.

Cheers,
Bernhard

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to