Question

I've created a class that keeps some information in its attributes. It contains add() method that adds a new set of information to all of the present in this class attributes.

I'd like its objects to behave like array offsets. For example, calling:

$obj = new Class[0];

would create the object containing the first set of information.

I'd also like to use foreach() loop on that class.

The changes of attributes should be denied from outside of the class, but I should have access to them.

Is that possible?

Was it helpful?

Solution

What you need is ArrayObject it implements IteratorAggregate , Traversable , ArrayAccess , Serializable , Countable altogether

Example

echo "<pre>";
$obj = new Foo(["A","B","C"]);
foreach ( $obj as $data ) {
    echo $data, PHP_EOL;
}

echo reset($obj) . end($obj), PHP_EOL; // Use array functions on object
echo count($obj), PHP_EOL; // get total element

echo $obj[1] ; // you can get element
$obj[0] = "D"; //  Notice: Sorry array can not be modified 

Output

A
B
C
AC
3
B

Class Used

class Foo extends ArrayObject {
    public function offsetSet($offset, $value) {
        trigger_error("Sorry array can not be modified");
    }
}

OTHER TIPS

This is how you can create multiple instance with different constructor values.

$objConfig = array( 
    array('id'=>1 , 'name'=>'waqar') , 
    array('id'=>2 , 'name'=>'alex')
);
$objects = array();

for($i=0; $i<count($objConfig) ; $i++)
{
    $objects[$i] = new ClassName($objConfig[$i]);
}

You need to implement ArrayAccess interface, examples are pretty straightforward.

Anyway I really discourage you from mixing classes and array behaviour for bad design purposes: array-wise accessing should be used just to keep syntax more concise.

Take full advantage of classes, magic methods, reflection: there's a bright and happy world out there, beyond associative arrays.

In this case, why do you not just have an array of your class instances? A very simple example:

/**
 * @var MyClass[]
 */
$myClasses = array();

$myClasses[] = new myClass();

Or alternatively use one of the more specialised SPL classes, here: http://php.net/manual/en/book.spl.php, such as SplObjectStorage (I haven't had a need for this, but it looks like it might be what you need)

Finally, you could roll your own, by simply creating a class that extends ArrayAccess and enforces you class type?

It really depends on what you need, for the vast majority of cases I would rely on storing classes in an array and enforcing any business logic in my model (so that array values are always the same class). This may be less performant, but assuming you're making a web app it is highly unlikely to be an issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top