From e9914e9d06b684a4b788584790767868bd7b7321 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Mon, 28 Jan 2008 22:48:15 +0000 Subject: [PATCH] - MFH Make SplObjectStorage implement ArrayAccess [DOC] --- NEWS | 8 ++-- ext/spl/internal/splobjectstorage.inc | 58 +++++++++++++++++++++++++-- ext/spl/spl_observer.c | 43 +++++++++++++++++++- 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index f08a2a8b28..cd95061e48 100644 --- a/NEWS +++ b/NEWS @@ -24,8 +24,11 @@ PHP NEWS DateTimeZone::getTranstions() to limit the range of transitions being returned. -- Added ability to store associative infor with objects in SplObjectStorage. - (Marcus) +- Improved SPL extension: + . Added ability to store associative information with objects in + SplObjectStorage. (Marcus) + . Added ArrayAccess support to SplObjectStorage. (Marcus) + . Added SplDoublyLinkedList, SplStack, SplQueue classes. (Etienne) - Added ability to use Traversable objects instead of plain arrays in ext/soap. (Joshua Reese, Dmitry) - Added "?:" operator. (Marcus) @@ -51,7 +54,6 @@ PHP NEWS (Etienne Kneuss) - Added "compact" handler for Zend MM storage. (Dmitry) - Added "+" and "*" specifiers to zend_parse_parameters(). (Andrei) -- Added SplDoublyLinkedList, SplStack, SplQueue classes. (Etienne) - Removed the experimental RPL (master/slave) functions from mysqli. (Andrey) diff --git a/ext/spl/internal/splobjectstorage.inc b/ext/spl/internal/splobjectstorage.inc index c7a56b43e1..b65aecaa96 100755 --- a/ext/spl/internal/splobjectstorage.inc +++ b/ext/spl/internal/splobjectstorage.inc @@ -20,7 +20,7 @@ * here therefore has a complexity of O(n) while the actual implementation has * complexity O(1). */ -class SplObjectStorage implements Iterator, Countable +class SplObjectStorage implements Iterator, Countable, ArrayAccess { private $storage = array(); private $index = 0; @@ -88,9 +88,9 @@ class SplObjectStorage implements Iterator, Countable return count($this->storage); } - /** @param obj object to look for + /** @param $obj object to look for * @return whether $obj is contained in storage - */ + */ function contains($obj) { if (is_object($obj)) @@ -106,7 +106,9 @@ class SplObjectStorage implements Iterator, Countable return false; } - /** @param $obj new object to attach to storage if not yet contained + /** @param $obj new object to attach to storage or object whose + * associative information is to be replaced + * @param $inf associative information stored along the object */ function attach($obj, $inf = NULL) { @@ -133,6 +135,54 @@ class SplObjectStorage implements Iterator, Countable } } } + + /** @param $obj new object to attach to storage or object whose + * associative information is to be replaced + * @param $inf associative information stored along the object + * @since 5.3.0 + */ + function offsetSet($obj, $inf) + { + $this->attach($obj, $inf); + } + + /** @param $obj Exising object to look for + * @return associative information stored with object + * @throw UnexpectedValueException if Object $obj is not contained in + * storage + * @since 5.3.0 + */ + function offsetGet($obj) + { + if (is_object($obj)) + { + foreach($this->storage as $idx => $element) + { + if ($object === $element[0]) + { + return $element[1]; + } + } + } + throw new UnexpectedValueException('Object not found'); + } + + /** @param $obj Exising object to look for + * @return associative information stored with object + * @since 5.3.0 + */ + function offsetUnset($obj) + { + $this->detach($obj); + } + + /** @param $obj object to look for + * @return whether $obj is contained in storage + */ + function offsetEsists($obj) + { + return $this->contains($obj); + } } ?> diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index d9d7dc2d09..16b27db420 100755 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -288,6 +288,25 @@ SPL_METHOD(SplObjectStorage, detach) intern->index = 0; } /* }}} */ +/* {{{ proto mixed SplObjectStorage::offsetGet($object) + Returns associated information for a stored object */ +SPL_METHOD(SplObjectStorage, offsetGet) +{ + zval *obj; + spl_SplObjectStorageElement *element; + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { + return; + } + element = spl_object_storage_get(intern, obj TSRMLS_CC); + if (!element) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Object not found"); + } else { + RETURN_ZVAL(element->inf,1, 0); + } +} /* }}} */ + /* {{{ proto bool SplObjectStorage::contains($obj) Determine whethe an object is contained in the storage */ SPL_METHOD(SplObjectStorage, contains) @@ -565,20 +584,39 @@ ZEND_BEGIN_ARG_INFO(arginfo_setInfo, 0) ZEND_ARG_INFO(0, info) ZEND_END_ARG_INFO(); +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, info) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_SplObjectStorage[] = { SPL_ME(SplObjectStorage, attach, arginfo_attach, 0) SPL_ME(SplObjectStorage, detach, arginfo_Object, 0) SPL_ME(SplObjectStorage, contains, arginfo_Object, 0) + SPL_ME(SplObjectStorage, getInfo, NULL, 0) + SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0) + /* Countable */ SPL_ME(SplObjectStorage, count, NULL, 0) + /* Iterator */ SPL_ME(SplObjectStorage, rewind, NULL, 0) SPL_ME(SplObjectStorage, valid, NULL, 0) SPL_ME(SplObjectStorage, key, NULL, 0) SPL_ME(SplObjectStorage, current, NULL, 0) SPL_ME(SplObjectStorage, next, NULL, 0) + /* Serializable */ SPL_ME(SplObjectStorage, unserialize, arginfo_Serialized, 0) SPL_ME(SplObjectStorage, serialize, NULL, 0) - SPL_ME(SplObjectStorage, getInfo, NULL, 0) - SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0) + /* ArrayAccess */ + SPL_MA(SplObjectStorage, offsetExists, SplObjectStorage, contains, arginfo_offsetGet, 0) + SPL_MA(SplObjectStorage, offsetSet, SplObjectStorage, attach, arginfo_offsetSet, 0) + SPL_MA(SplObjectStorage, offsetUnset, SplObjectStorage, detach, arginfo_offsetGet, 0) + SPL_ME(SplObjectStorage, offsetGet, arginfo_offsetGet, 0) {NULL, NULL, NULL} }; @@ -595,6 +633,7 @@ PHP_MINIT_FUNCTION(spl_observer) REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable); REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator); REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Serializable); + REGISTER_SPL_IMPLEMENTS(SplObjectStorage, ArrayAccess); return SUCCESS; } -- 2.40.0