📜 ⬆️ ⬇️

Object collections in PHP

Over the past 5 years I have been working with PHP. He has enough different problems, but it never stopped to create well-working products.

Despite this, there are a number of things that are performed inside quite “crookedly”. One of the questions that was constantly wasting my nerves was the issue of working with sets of objects using an array of data.

In my opinion, arrays in PHP have fairly wide functionality, which, by the way, is one of the problems when working with sets of objects.

What didn't you like?

')
As a result, it was decided to create a package that should work with sets of similar objects (collections).

And so, I present to your attention the package Rmk \ Collection.

Interfaces


Collection interfaces are designed to describe the functionality and classification of collection types.

The basic interface of collections is the Collection interface.

The Map, Set, List, Queue, and Deque interfaces inherit the Collection interface and add their own functionality.

The Iterable interface is used to bypass collection objects. It is supported by all collection interfaces.

image

Iterable
This interface provides the ability to crawl collection objects and apply a custom function to each object.

Collection
This interface is designed to describe the basic functions of working with a variety of objects. It inherits the Countable and Iterable interfaces, which allows you to get the number of objects in a collection and to crawl and apply a custom function for each collection object. The collection interface implies that the collection contains objects of the same type.

Map
This interface is intended to describe the functionality of the site map. The object map is intended for building associative links between objects, where one of the objects is a key and the other value. The object map interface implies that there are keys of the same type in the card. The object map interface implies that the map contains values ​​of the same type. The object map interface inherits the Collection interface.

Set
This interface is intended to describe the functionality of a set of objects, where objects are unique within the collection. Uniqueness of objects is performed using the getIdentity () method. The object collection interface inherits the Collection interface.

Queue
This interface is intended to describe the functionality of the object queue. The object queue is intended to describe the data structure when objects are added to the end of the queue, and are taken from the beginning of the queue. The object queue interface inherits the Collection interface.

Deque
This interface is intended to describe the functionality of a bidirectional object queue. The bidirectional object queue interface inherits the Queue object queue interface and adds additional functionality. Bidirectional object queue functionality involves working with the queue on both sides.

Sequentiallist
This interface is intended to describe the functionality of the list of objects. A list of objects is a sequence of objects, where objects are stored under consecutive integer indices. In addition to the general functionality of the list of objects, this interface defines a reverseEach () method similar to the Iterable :: each () method, except that the reverseEach () method walks the list in the reverse order. The object list interface inherits the Collection interface.

Card implementations



Maps are represented by implementations of HashMap and HashStore.

Part of the HashMap and HashStore functionality is inherited from AbstractCollection and AbstractMap abstract classes.

The internal structure of the HashMap and HashStore maps is based on a network of associative links. This makes it possible to implement all card operations using associative samples, which greatly increases their speed. The complexity of the card algorithms is O (1), which means that the installation / retrieval time of objects does not change depending on the size of the maps.

HashMap and HashStore cards support any type of data for keys and values. This is a functional advantage over standard Php arrays.

The keys of the HashMap card are unique. HashMap map values ​​are not unique, which allows you to associate one value with multiple keys.

The keys and values ​​of the HashStore map are unique, which allows you to organize a storage of unique associated objects.

The HashStore card is on average 20% faster than the HashMap card. This advantage is obtained due to the uniqueness of the objects in the HashStore, which requires a smaller number of associative links.

image

Set implementations


The sets are represented by the only implementation of UniqueStore.

Objects in the store UniqueStore. The uniqueness of the objects is provided by the getIdentity () method, which returns object identifiers. Multiple objects with the same identifier cannot be present in the UniqueStore.

The internal structure of the storage of unique objects UniqueStore is built on the basis of associative links between objects and their identifiers. This makes it possible to implement all storage operations using associative samples, which greatly increases its speed. The complexity of the unique object storage algorithms is O (1), which means that the installation / retrieval time of the objects does not change depending on the size of the storage.

The storage of unique objects UniqueStore supports any data types for values.
image

List implementations


Lists are represented by implementations of ArrayList and LinkedList.

ArrayList and LinkedList object lists maintain a sequential order of indexes when their structure changes.

The performance of the lists of the ArrayList and LinkedList objects depends on the number of changes in their structure. Proceeding from this, the operations of work with the end of the list (add / delete) are the “cheapest”, and the operations of the beginning of the list (add / delete) are the most “expensive”. The complexity of the work of the object list algorithms is O (n * (count - index)), where n is an operation; count - the size of the list; index - the index on which the operation is performed.

ArrayList and LinkedList object lists support any data types for values.

LinkedList's linked object list implements the bidirectional queue interface of Deque objects and inherits the functionality from ArrayList.

image

Queuing implementations


Specific queue implementations are missing, since LinkedList's linked list perfectly covers their functionality.

Some examples of use


Examples of using cards:
<?php namespace Rmk\Collection; use \UnexpectedValueException as UnexpectedValueException; use \InvalidArgumentException as InvalidArgumentException; use \stdClass as stdClass; include '../../bootstrap.php'; $map = new HashMap('stdClass', 'string'); $obj1 = new stdClass(); $obj2 = new stdClass(); $obj3 = new stdClass(); //    / . $map->set('k1', $obj1); $map->set('k2', $obj2); $map->set('k3', $obj3); try { $map->set(27, $obj1); } catch (InvalidArgumentException $exc) { echo '    .'; } try { $map->set('k4', new UnexpectedValueException); } catch (InvalidArgumentException $exc) { echo '    .'; } //  . $map->each(function($value, $key, $thisMap) { /** * @TODO:  . */ } ); //   . $map->remove($obj1); $map->remove($obj2); //   . $map->removeKey('k3'); if ($map->isEmpty()) { /** * @TODO:  ,   ? */ } //   . $array = $map->toArray(); // !     ,    //  . $objectMap = new HashMap('stdClass', 'stdClass'); try { $objectArray = $objectMap->toArray(); } catch (UnexpectedValueException $exc) { echo '     .'; } 


Examples of using kits:
 <?php namespace Rmk\Collection; use \UnexpectedValueException as UnexpectedValueException; use \InvalidArgumentException as InvalidArgumentException; use \stdClass as stdClass; include '../../bootstrap.php'; $set = new UniqueStore('stdClass'); $obj1 = new stdClass(); $obj2 = new stdClass(); $obj3 = new stdClass(); //    . $set->add($obj1); $set->add($obj2); $set->add($obj3); //       . $set->add($obj3); try { $set->add(new UnexpectedValueException); } catch (InvalidArgumentException $exc) { echo '    .'; } //  . $set->each(function($value, $thisSet) { /** * @TODO:  . */ } ); //    . $set->remove($obj1); $set->remove($obj2); $set->remove($obj3); //   . $array = $set->toArray(); 


Examples of using lists:
 <?php namespace Rmk\Collection; use \UnexpectedValueException as UnexpectedValueException; use \InvalidArgumentException as InvalidArgumentException; use \OutOfRangeException as OutOfRangeException; use \stdClass as stdClass; include '../../bootstrap.php'; $list = new LinkedList('stdClass'); $obj1 = new stdClass(); $obj2 = new stdClass(); $obj3 = new stdClass(); //    . $list->add(0, $obj1); $list->add(1, $obj2); $list->add(2, $obj3); try { $list->add(4, $obj1); } catch (OutOfRangeException $exc) { echo '     ,   .'; } //  . $list->each(function($value, $index, $thisList) { /** * @TODO:  . */ } ); //     . $list->reverseEach(function($value, $index, $thisList) { /** * @TODO:  . */ } ); //   . $list->remove($obj1); $list->removeIndex(0); $list->removeFirst(); if ($list->isEmpty()) { echo ' .'; } 


Advantages and disadvantages




Source codes


https://github.com/rmk135/Rmk-Framework

Source: https://habr.com/ru/post/144182/


All Articles