Comments 10
Конечно это все здорово, но почему бы не использовать MVC или хотя бы часть его, для всего этого. Есть тысячи компонентов и фреймворков для работы с формами, HTTP запросами, моделями, сессиями и прочим, а Вы создали странный костыль, который не несет никакого полезного функционала, а лишь подсказывает свойство в автокомплите. Таким же образом можно и ArrayObject дополнить аннотацией "@ property" ведь все равно свойство модели нужно описать, но ко всему у него нативная скорость работы.
С формами согласен. Но есть проекты без фреймворков.
Также ни кто не запрещает в дочерних классах запретить __set.
Тот же самый Yii дает возможность работать с сессиями как с массивом, а мы хотим как с объектом.
Можно конечно сериализовать свой объект и десереализовать, можно обернуть массив.
Тут обертка больше для json подходит. Отсутствует проверка на isset или key_exist, если нет переменной — получим null.
Опять же это можно инкапсулировать в любом методе get (например дефолтное значение).
Идея была в том, что в будущем можно изменить наши классы под изменение в системе. И все изменения останутся в одном дереве классов, а не по всему проекту с конструкциями isset и т.д.
А MVC — не панацея. В модели можно использовать наше дерево классов и сделать свой фасад и т.д.

Заголовок
json
{
  "pagination": {
    "next_max_tag_id": "1404127307134234",
    "deprecation_warning": "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead",
    "next_max_id": "1404127307134234",
    "next_min_id": "1404412273269367",
    "min_tag_id": "1404412273269367",
    "next_url": "https://api.instagram.com/v1/tags/yrakir/media/recent?access_token=1413531024.60************************319f2a26b8a&max_tag_id=1404127307134234"
  },
  "meta": {
    "code": 200
  },
  "data": [
    {
      "attribution": null,
      "tags": [
        "фокусник",
        "иллюзионист",
        "ведущий",
        "волшебник",
        "yrakir",
        "ведущийиллюзионистюрийкир89299142016",
        "юрийкир",
        "юракир"
      ],
      "type": "image",
      "location": {
        "latitude": 55.8588,
        "longitude": 37.567405
      },
      "comments": {
        "count": 0,
        "data": []
      },
      "filter": "X-Pro II",
      "created_time": "1404412273",
      "link": "http://instagram.com/p/p_8ET7Kkh3/",
      "likes": {
        "count": 36,
        "data": [
          {
            "username": "timofeev081",
            "profile_picture": "http://images.ak.instagram.com/profiles/profile_197497217_75sq_1382615347.jpg",
            "id": "197497217",
            "full_name": "Pavel Timofeev"
          },
          {
            "username": "denissmile5",
            "profile_picture": "http://images.ak.instagram.com/profiles/profile_196038812_75sq_1394347739.jpg",
            "id": "196038812",
            "full_name": "denissmile5"
          },
          {
            "username": "sitnikovalyusia",
            "profile_picture": "http://images.ak.instagram.com/profiles/profile_299334845_75sq_1360006870.jpg",
            "id": "299334845",
            "full_name": "Людмила Ситникова"
          },
          {
            "username": "valeryana_pashkova",
            "profile_picture": "http://photos-g.ak.instagram.com/hphotos-ak-xpa1/924007_817454458267534_846281437_a.jpg",
            "id": "191689127",
            "full_name": "Matil•Da"
          }
        ]
      },
      "images": {
        "low_resolution": {
          "url": "http://scontent-a.cdninstagram.com/hphotos-xpa1/t51.2885-15/10507870_1473305886242980_1292181890_a.jpg",
          "width": 306,
          "height": 306
        },
        "thumbnail": {
          "url": "http://scontent-a.cdninstagram.com/hphotos-xpa1/t51.2885-15/10507870_1473305886242980_1292181890_s.jpg",
          "width": 150,
          "height": 150
        },
        "standard_resolution": {
          "url": "http://scontent-a.cdninstagram.com/hphotos-xpa1/t51.2885-15/10507870_1473305886242980_1292181890_n.jpg",
          "width": 640,
          "height": 640
        }
      },
      "users_in_photo": [],
      "caption": {
        "created_time": "1404412273",
        "text": "КОПЧИК - это маленький полицейский !!! #юракир #юрийкир #yrakir #ведущий #волшебник #ведущийиллюзионистюрийкир89299142016 #фокусник #иллюзионист",
        "from": {
          "username": "yrakir",
          "profile_picture": "http://images.ak.instagram.com/profiles/profile_259027705_75sq_1398769213.jpg",
          "id": "259027705",
          "full_name": "Иллюзионист +79299142016"
        },
        "id": "756587441920035212"
      },
      "user_has_liked": false,
      "id": "756587441483827319_259027705",
      "user": {
        "username": "yrakir",
        "website": "",
        "profile_picture": "http://images.ak.instagram.com/profiles/profile_259027705_75sq_1398769213.jpg",
        "full_name": "Иллюзионист +79299142016",
        "bio": "",
        "id": "259027705"
      }
    }
  ]
}

Учитывая, что существуют микрофреймворки, например Silex, и что эти же микрофреймворки можно прикручивать и к существующим проектам, которые без фреймворков, то писать проекты «без фреймворков» можно только в учебных целях.

Даже в учебных целях лучше изучить какой-то популярный инструмент, при этом получить опыт, поддержку от сообщества и возможность расширять проект.
А зачем было писать ArrayClass? Есть же встроенный ArrayObject.

ArrayObject implements IteratorAggregate , ArrayAccess , Serializable , Countable


Он же возвращает встроенный ArrayIterator.

public ArrayIterator getIterator ( void )


arrayobject
arrayiterator

ArrayIterator легко далее сделать рекурсивным, уже сами погуглите recursive.

Зачем изобретать велосипеды? Разве что в учебных целях.
Правильнее было бы максимально использовать встроенный объекты и SPL по максимуму.

А если уж делать свою коллекцию, по которой хочется итерироваться сразу, то как-то так.

class Collection implements
\ArrayAccess, \Serializable, \Iterator, \Countable


Для примера реализации можно взглянуть на ArrayCollection от Doctrine.

Collection
ArrayCollection
Идея была именно в жесткой связи с IDE и ухода от isset
$a = new ArrayObject();

var_dump($a->my);
$a->my = 1;
var_dump($a->my);

echo "======\n";
$ar = array();
$a = new ArrayClass($ar);

var_dump($a->my);
$a->my = 1;
var_dump($a->my);

[web@centos html]$ php test.php
PHP Notice:  Undefined property: ArrayObject::$my in /home/web/html/test.php on line 13
NULL
int(1)
======
NULL
int(1)


и во втором случае IDE сразу подчеркивает «access via magic metod»
также Code Inspect дает сразу 3 ошибки. Чего не происходит в первом случае.

ну и
print_r($ar);
Array
(
    [my] => 1
)



и на месте $ar может быть любой системный массив. ($_GET, $_POST) и т.д.
Даже если моя реализация тяжелее, она завязана на IDE и сразу показывает где у нас могут быть ошибки, что не скажешь про ArrayObject

И «навешивать» сразу много интерфейсов не есть хорошо. Они могут ни когда не пригодиться, нужны будут — люди довесят. Я не привел законченное решение, и это не библиотека. Люди захотят — изменят/используют. Просто идея по некой типизации массивов.

ArrayObject создает копии массивов.
Представьте, у вас 1000000 элементов.
В ArrayClass все ацессоры работают через нативные методы + мы используем существующую память, а не стараемся ее раздувать копированием массивов.

var_dump($a->my);
$a->my = 1;
var_dump($a->my);
$ar['my'] = 2;
var_dump($a->my);

print_r($ar);
ar = array();

for($i=0; $i<1000; $i++){
    $ar[$i] = $i;
}

//memory usage (895752)
//$a = new ArrayObject($ar);

//memory usage (799632)
$a = new ArrayClass($ar);

var_dump($a->my);
$a->my = 1;
var_dump($a->my);
var_dump($ar['my']);
Вот еще пару мини решений, чтобы уйти от isset

get-in
LazyAccess-to-PHP-arrays

Вторая ссылка похожа на ваш ArrayClass по идее.

NetBeans не показывает, что вызов через магический метод. Это фишка PhpStorm.
Ну у меня есть единомышленники :)
Ну и еще
Netbeans:

Netbeans
image

Проблема в том, что комменты она не все ест, а так эффект такой же. Или вы не об этом?
Only those users with full accounts are able to leave comments. Log in, please.