SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)

    Question Square bracket method in a class?

    Is it possible to declare a [] style method in a class? (Sorry I'm not at a dev machine right now to run a simple test.)

    class Items
    {

    private $_items = array();

    // code removed...

    public function this[$index]
    {
    // return something
    }

    // more code removed...

    }

  2. #2
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,222
    Mentioned
    153 Post(s)
    Tagged
    0 Thread(s)
    I think you may want to look at this article

    Implementing Iterator or IteratorAggregate is likely what you want.

  3. #3
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    I'm already doing that. I'm authoring both a Collection class and a Dictionary class. The difference being that the Collection class doesn't accept a $key. It operates purely on index. For example:

    $d = new Dictionary();
    $d->Add('Primary', $primaryObj);
    $d->Add('Secondary', $secondaryObj);
    // key MUST be a non-null, non-empty string

    $c = new Collection();
    $c->Add($primaryObj);
    $c->Add($secondaryObj);
    // this just uses numeric indexes

    What I'd like to be able to do though is...

    $c[2] = $replacementObj;

    Instead of...

    $c->Replace(2, $replacementObj);

    Can this be done?

  4. #4
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,222
    Mentioned
    153 Post(s)
    Tagged
    0 Thread(s)
    Gotcha.

    If you go to php.net/Iterator, the comment by wavetrex A(nospam)T gmail DOT com seems to be what you want to accomplish.

    I haven't read through all of the comments yet so there may be a better solution than his, but he did do a proof-of-concept of the idea you are wanting to implement.

  5. #5
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,222
    Mentioned
    153 Post(s)
    Tagged
    0 Thread(s)
    Just an FYI, same page further down, comment by just_somedood at yahoo dot com

    Seems you can implement ArrayAccess to get to what you are wanting to do.

  6. #6
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Brilliant. I'll try it out when I can and let you know if it works.

  7. #7
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,222
    Mentioned
    153 Post(s)
    Tagged
    0 Thread(s)
    Please do let me know if it works, as I too will likely attempt this in the near future too, would definitely like to know your experience.

  8. #8
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Success!

    ICollator.interface.phps
    PHP Code:
    <?php

    interface ICollator extends ArrayAccessCountableIteratorAggregate
    {

    }

    ?>
    Collator.class.phps
    PHP Code:
    <?php

    abstract class Collator implements ICollator
    {

        protected 
    $_items = array();

        protected function 
    __construct(ICollator $collator null)
        {
            
            if (!
    is_null($collator))
                foreach (
    $collator as $offset => $value)
                    
    $this->_items[$offset] = $value;

        }

        public function 
    OffsetExists($offset)
        {

            return 
    array_key_exists($offset$this->_items);

        }

        public function 
    OffsetGet($offset)
        {

            if (
    $this->offsetExists($offset))
                return 
    $this->_items[$offset];
            else
                throw new 
    Exception('Requested offset was not found!');
            
        }

        public function 
    OffsetSet($offset$value)
        {

            if (
    $this->offsetExists($offset))
                
    $this->_items[$offset] = $value;
            else
                throw new 
    Exception('Requested offset was not found!');

        }

        public function 
    OffsetUnset($offset)
        {

            throw new 
    Exception('Unsetting an element is not allowed!');

        }

        public function 
    Count()
        {

            return 
    count($this->_items);

        }

        public function 
    GetIterator()
        {

            return new 
    ArrayIterator($this->_items);

        }

    }

    ?>
    ICollection.interface.phps
    PHP Code:
    <?php

    interface ICollection extends ICollator
    {

        function 
    Add($value);

        function 
    Contains($value);

        function 
    Remove($value);

    }

    ?>
    Collection.class.phps
    PHP Code:
    <?php

    class Collection extends Collator implements ICollection
    {

        public function 
    __construct(ICollection $collection null)
        {

            
    parent::__construct($collection);        

        }

        public function 
    Add($value)
        {

            if (!
    $this->Contains($value))
                
    $this->_items[] = $value;

        }

        public function 
    Contains($value)
        {

            return 
    in_array($valuearray_values($this->_items));

        }

        public function 
    Remove($value)
        {

            if (
    $this->Contains($value))
                unset(
    $this->_items[array_search($value$this->_items)]);
                
        }

    }

    ?>
    IDictionary.interface.phps
    PHP Code:
    <?php

    interface IDictionary extends ArrayAccessCountableIteratorAggregate
    {

        function 
    Add($key$value);

        function 
    Contains($value);

        function 
    Keys();

        function 
    Remove($key);

        function 
    Values();

    }

    ?>
    Dictionary.class.phps
    PHP Code:
    <?php

    class Dictionary extends Collator implements IDictionary
    {

        public function 
    __construct(IDictionary $dictionary null)
        {

            
    parent::__construct($dictionary);        

        }

        public function 
    Add($key$value)
        {

            if (!
    is_string($key) || is_null($key) || empty($key))
                throw new 
    Exception('String key expected!');

            if (!
    $this->Keys()->Contains($key))
                
    $this->_items[$key] = $value;

        }

        public function 
    Contains($value)
        {

            return 
    in_array($valuearray_values($this->_items));

        }

        public function 
    Keys()
        {

            
    $keys = new Collection();

            foreach (
    array_keys($this->_items) as $key)
                
    $keys->Add($key);

            return 
    $keys;

        }

        public function 
    Remove($key)
        {

            if (
    $this->Keys()->Contains($key))
                unset(
    $this->_items[$key]);

        }

        public function 
    Values()
        {

            
    $values = new Collection();

            foreach (
    array_values($this->_items) as $value)
                
    $values->Add($value);

            return 
    $values;

        }

    }

    ?>
    Usage
    PHP Code:

    // creating collections
    $collection = new Collection();
    $collection = new Collection($existing);

    // adding to a collection
    $collection->Add($item);

    // testing inclusion in a collection
    if ($collection->Contains($item))
    {
        
    // do something
    }

    // getting a collection value
    $item $collection[0];

    // setting a collection value
    $collection[0] = $item;

    // removing a collection value
    $collection->Remove($item);

    // creating dictionaries
    $dictionary = new Dictionary();
    $dictionary = new Dictionary($existing);

    // adding to a dictionary
    $dictionary->Add($key$item);

    // testing key inclusion in a dictionary
    if ($dictionary->Keys()->Contains($key))
    {
        
    // do something
    }

    // testing item inclusion in a dictionary
    if ($dictionary->Values()->Contains($item))
    {
        
    // do something
    }
    // or
    if ($dictionary->Contains($item))
    {
        
    // do something
    }

    // getting a dictionary value
    $item $dictionary["key"];

    // setting a dictionary value
    $dictionary["key"] = $item;

    // removing a dictionary value
    $dictionary->Remove($key); 
    As you can see, it is built to be extensible, so feel free to come up with your own implementations of Collator. I will probably do a typecast version where I extend Collator to TypedCollator and pass in $type before the optional collator instance. You could also do a read only version if you wanted.

    =)

  9. #9
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Here, I cleaned up the code a little, added a few exceptions and cut out a few 'else' statements.
    Attached Files Attached Files

  10. #10
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,222
    Mentioned
    153 Post(s)
    Tagged
    0 Thread(s)
    Great, glad it worked out! Thanks for the code too, that will surely come in handy.

  11. #11
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by Serenarules View Post
    Here, I cleaned up the code a little, added a few exceptions and cut out a few 'else' statements.
    Nice code @Serenarules ; , this certainly will help others, and also for your help @cpradio ;.

    Steve
    ictus==""

  12. #12
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    You're welcome. =)


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •