As you know ArrayObject is not an array so you can't use the built in array functions. Here's a trick around that:
Extend the ArrayObject class with your own and implement this magic method:
<?php
public function __call($func, $argv)
{
if (!is_callable($func) || substr($func, 0, 6) !== 'array_')
{
throw new BadMethodCallException(__CLASS__.'->'.$func);
}
return call_user_func_array($func, array_merge(array($this->getArrayCopy()), $argv));
}
?>
Now you can do this with any array_* function:
<?php
$yourObject->array_keys();
?>
- Don't forget to ommit the first parameter - it's automatic!
Note: You might want to write your own functions if you're working with large sets of data.ArrayObject
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
ArrayObject
Референца за `class.arrayobject.php` со подобрена типографија и навигација.
Класата ArrayObject
класата mysqli_driver
Вовед
Оваа класа овозможува објектите да функционираат како низи.
Забелешка: Обвиткувањето објекти со оваа класа е фундаментално погрешно, и затоа неговата употреба со објекти не се препорачува.
Синопсис на класата
$array = [], int $flags = 0, string $iteratorClass = ArrayIterator::class)Претходно дефинирани константи
Знаменца на ArrayObject
ArrayObject::STD_PROP_LIST-
Својствата на објектот ја имаат својата нормална функционалност кога се пристапува како листа (var_dump(),
foreach, итн.). ArrayObject::ARRAY_AS_PROPS-
Записите може да се пристапат како својства (читање и запишување). ArrayObject класата користи сопствена логика за пристап до својствата, така што не се прикажува предупредување или грешка при обид за читање или запишување динамички својства.
Содржина
- ArrayObject::append — Додава вредност
- ArrayObject::asort — Ги сортира записите по вредност
- ArrayObject::__construct — Конструира нова низа објект
- ArrayObject::count — Го добива бројот на јавни својства во ArrayObject
- ArrayObject::exchangeArray — Ја менува низата со друга
- ArrayObject::getArrayCopy — Создава копија на ArrayObject
- ArrayObject::getFlags — Ги добива знаменцата за однесување
- ArrayObject::getIterator — Создава нов итератор од инстанца на ArrayObject
- ArrayObject::getIteratorClass — Го добива името на класата на итераторот за ArrayObject
- ArrayObject::ksort — Ги сортира записите по клуч
- ArrayObject::natcasesort — Сортирај низа користејќи алгоритам за „природно нарачување“ што не ги зема предвид големите и малите букви
- ArrayObject::natsort — Ги сортира записите користејќи алгоритам за „природно нарачување“
- ArrayObject::offsetExists — Враќа дали бараниот индекс постои
- ArrayObject::offsetGet — Враќа вредност на наведениот индекс
- ArrayObject::offsetSet — Ја поставува вредноста на наведениот индекс на newval
- ArrayObject::offsetUnset — Ја брише вредноста на наведениот индекс
- ArrayObject::serialize — Серијализира ArrayObject
- ArrayObject::setFlags — Поставува знаменца за однесување
- ArrayObject::setIteratorClass — Ги поставува знаменцата за однесување
- ArrayObject::uasort — Го поставува името на класата на итераторот за ArrayObject
- ArrayObject::uksort — Ги сортира записите со кориснички дефинирана функција за споредба и одржува асоцијација на клучеви
- ArrayObject::unserialize — Ги сортира записите по клучеви со кориснички дефинирана функција за споредба
Белешки од корисници 10 белешки
There is a better explanation about the ArrayObject flags (STD_PROP_LIST and ARRAY_AS_PROPS) right here:
http://stackoverflow.com/a/16619183/1019305
Thanks to JayTaphIf you need the last key of your collection use:
<?php
array_key_last($this->getArrayCopy())
?>
In an extending class it could look like:
<?php
class Collection extends ArrayObject
{
public function lastKey(): int
{
return array_key_last($this->getArrayCopy());
}
}
?>
If you want to use any type safe collection:
<?php
class BookCollection extends Collection
{
public function add(Book $book) : void
{
$this->offsetSet($book->id, $book);
}
// note the return type "Book"
public function get(int $bookId) : Book
{
$this->offsetGet($bookId);
}
}
?>I found the description of STD_PROP_LIST a bit vague, so I put together a simple demonstration to show its behavior:
<?php
$a = new ArrayObject(array(), ArrayObject::STD_PROP_LIST);
$a['arr'] = 'array data';
$a->prop = 'prop data';
$b = new ArrayObject();
$b['arr'] = 'array data';
$b->prop = 'prop data';
// ArrayObject Object
// (
// [prop] => prop data
// )
print_r($a);
// ArrayObject Object
// (
// [arr] => array data
// )
print_r($b);
?>Generally variable $this can't be used as an array within an object context. For example, following code piece would cause a fatal error:
<?php
class TestThis {
public function __set($name, $val) {
$this[$name] = $val;
}
public function __get($name) {
return $this[$name];
}
}
$obj = new TestThis();
$obj->a = 'aaa';
echo $obj->a . "\n";
?>
But things are different when $this is used in an ArrayObject object. e.g., following code piece are valid:
<?php
class TestArrayObject extends ArrayObject {
public function __set($name, $val) {
$this[$name] = $val;
}
public function __get($name) {
return $this[$name];
}
}
$obj = new TestArrayObject();
$obj->a = 'aaa';
echo $obj->a . "\n";
?>// Example STD_PROP_LIST and ARRAY_AS_PROP combined
<?php
$ao = new ArrayObject();
$ao ->setFlags(ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS);
$ao->prop = 'prop data';
$ao['arr'] = 'array data';
print_r($ao);
?>
// Result
ArrayObject Object
(
[storage:ArrayObject:private] => Array
(
[prop] => prop data
[arr] => array data
)
)You can easily realise that ArrayObject can use various functions as they are in ArrayIterator to iterate an object-as-a-array. However, you need to "activate" these function (rewind, valid, next and so on...) by using getIterator() first. Actually this function inherits from Iterator Aggregate interface.
Take a look at the following basic example. The results are the same:
<?php
$array = [1, 2, 3, 4];
$a = new ArrayObject($array);
$b = new ArrayIterator($array);
$iterator = $a->getIterator();
for($iterator->rewind(); $iterator->valid(); $iterator->next()){
echo $iterator->current()*2;
}
for($b->rewind(); $b->valid(); $b->next()){
echo $b->current()*2;
}
//Resulst are the same 2468 AND 2468If you want numerical ArrayObject objects to play nice with json_encode(), implement JsonSerializable:
class JsonSerializableArrayObject extends ArrayObject implements JsonSerializable {
function jsonSerialize() {
return $this->getArrayCopy();
}
}
For assoc ArrayObject objects this isn't neccesary, but for numerical arrays it is, otherwise they will be formatted like
{"0":"jaap","1":"karel"}
instead of
["jaap","karel"]If you plan to derive your own class from ArrayObject, and wish to maintain complete ArrayObject functionality (such as being able to cast to an array), it is necessary to use ArrayObject's own private property "storage".
Since that is impossible to do directly, you must use ArrayObject's offset{Set,Get,Exists,Unset} methods to manipulate it indirectly.
As a side benefit, this means you inherit all the iteration and other functions in complete working order.
This may sound obvious to someone who has never implemented their own ArrayObject class... but it is far from so.
<?php
class MyArrayObject extends ArrayObject {
static $debugLevel = 2;
static public function sdprintf() {
if (static::$debugLevel > 1) {
call_user_func_array("printf", func_get_args());
}
}
public function offsetGet($name) {
self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args()));
return call_user_func_array(array(parent, __FUNCTION__), func_get_args());
}
public function offsetSet($name, $value) {
self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args()));
return call_user_func_array(array(parent, __FUNCTION__), func_get_args());
}
public function offsetExists($name) {
self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args()));
return call_user_func_array(array(parent, __FUNCTION__), func_get_args());
}
public function offsetUnset($name) {
self::sdprintf("%s(%s)\n", __FUNCTION__, implode(",", func_get_args()));
return call_user_func_array(array(parent, __FUNCTION__), func_get_args());
}
}
$mao = new MyArrayObject();
$mao["name"] = "bob";
$mao["friend"] = "jane";
print_r((array)$mao);
/* Output:
offsetSet(name,bob)
offsetSet(friend,jane)
Array
(
[name] => bob
[friend] => jane
) */
?>
If you wish to use the "Array as Properties" flag, you simply need to include this in your constructor:
<?php parent::setFlags(parent::ARRAY_AS_PROPS); ?>
This will allow you to do things such as the below example, without overriding __get or __set .
<?php
$mao->name = "Phil";
echo $mao["name"]; /* Outputs "Phil" */
?>If you want to use built-in array function with ArrayObject, store the iterator instance and return the value as reference in offsetGet.
<?php
class Collection extends \ArrayObject {
public function __construct(array $data = [])
{
if (!\is_array($data) && !\array_key_exists('ArrayAccess', class_implements($data))) {
$data = [$data];
}
$this->iterator = $this->getIterator();
parent::__construct($data);
}
public function &offsetGet($index)
{
$value = &$this->iterator[$index] ?? null;
return $value;
}
}
?>