Download the PHP package earc/data without Composer

On this page you can find all versions of the php package earc/data. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package data

earc/data

Strongly decoupled data component of the eArc libraries.

Use this library if you want maximal control of the persistence process. Update/request your databases, caches, search indices, etc. during entity persistence/load processing in an optimal order determined by your project. You can even exchange them, stack them up or remove parts with minimal effort and without touching your business logic.

It works best with key-value based persistence like you would use with a redis server backed up by a search index server like elasticsearch, and a memory based entity caching. Checkout the eArc components earc/data-redis and earc/data-elasticsearch earc/data-elasticsearch for easy integration.

The usage of a traditional sql databases is possible too, but comes with a bit more effort on your side. Check the writing your own bridge section for a deeper insight.

table of contents

pro/cons

pro

cons

installation

Install the earc data library via composer.

basic usage

The data_* functions need to be imported. Use this in yourindex.php, bootstrap or configuration script.

Then register your persistence infrastructure to the onLoad, onPersit, onRemove, onFind and onAutoPrimaryKey events.

After that entities can be loaded and saved via the data_* functions.

You can call the data_* functions from everywhere (i.e. constructors, methods, vanilla functions or plain code).

classes

There are five types of entity related objects pure entities, collections of pure entities, embedded entities, embedded collections and immutable entities. The related interfaces are used in the persisting/loading process.

entities

Entities are objects that are associated to a primary key, to identify them (in combination with their class name) for loading. They implement the EntityInterface and the PrimaryKeyInterface. To create an entity class just extend the AbstractEntity class and wire the primaryKey property.

For reverencing entities within other entities you have to use the primary key as property (like you would do it in a sql database).

This gives the advantage, that reverences between entities does not need to be managed by earc/data, and your reverenced entity is lazy loaded. Both saves a lot of overhead and gives you more control without doing much more programming.

collections

Reverencing many entities follows the same principles. To make it easy use the Collection class. The presence of the CollectionInterface is mandatory for the persistence/loading process.

Collections consist always of one type of entities.

Hint: If you extend the type of the entities used by your collection, you can add instances of this to the collection, but earc/data neither guarantees that the additional data is saved nor that it is not.

embedded entities

If two entities are strongly coupled (one entity is needed nearly every time while working with the other and vice versa) for example within xml like document structures or products and their attributes, you should consider using embedded entities. They may have a better performance on loading and saving as the underlying datastructure is hit only once.

Embedded entities are saved and loaded with the root entity. The root entity is always a pure entity and has a primary key. The embedded entities do not have a primary key. They always hold a reverence to their parent (the embedding) entity. Embedded entities may be embedded within other embedded entities. They can form an entity tree.

They implement the EmbeddedEntityInterface. To create an embedded entity class just extend the AbstractEmbeddedEntity class and wire the ownerEntity property.

embedded collections

Embedded collections are collections of embedded entities embedded within other entities. Use the EmbeddedCollection class for them. The presence of the EmbeddedCollectionInterface is mandatory for the persistence/loading process.

Embedded collections consist always of one type of entities.

Hint: If you extend the type of the entities used by your collection, you can add instances of this to the collection and this time earc/data guarantees that the additional data is saved.

Embedded collections expose a findBy() method to search the collection in a key value based fashion.

Hint: If you reverence an object by a property of an entity that is no embedded entity and not an embedded collection earc/data neither guarantees that the data of the property is saved nor that it is not. It should be avoided, but it is not permitted. If you use your own bridge and serializer it may make sense.

functions

earc/data uses functions instead of services to give maximal freedom to your code.

data persist

data_persist takes one entity as argument. The data of the entity will be saved. If the getPrimaryKey() method returns null an exception is thrown. There is only one exception to the rule: if the entity implements the OnAutoPrimaryKeyInterface and at least one callable registered to the OnAutoPrimaryKeyInterface event returns a string result. Then this result is used as primary key.

On calling data_persist all entities scheduled via data_schedule will be saved first. data_persist can be called without argument, to trigger the saving of the scheduled entities without the need to explicit save any entity.

To save multiple entities there is a data_persist_batch function.

data load

data_load takes the class name and primary key as arguments. It returns the entity.

data_load returns the same instance on successive calls when the same arguments are provided.

You can change this behaviour by calling data_detach in between. Please note the resulting behaviour might be unexpected for inattentive developers. Use with great care.

data_load takes a third facultative flag. If it is set to DataStoreInterface::LOAD_FLAG_USE_FIRST_LEVEL_CACHE_ONLY, only entities already loaded are returned. If it is set to DataStoreInterface::LOAD_FLAG_SKIP_FIRST_LEVEL_CACHE, earc/data does not look up the already loaded entities and does not add the loaded entities to the already loaded ones - the retrieved entities are in a detached state and will be another instance than the same entities loaded before or after that.

There is a data_load_batch function to load multiple entities at once.

data delete

data_delete takes an entity as argument. It removes the entity data.

Entities implementing the ImmutableEntityInterface can only be deleted if the force flag has been set.

This function has a multiple counterpart data_delete_batch.

data remove

data_remove takes the entity class name and primary key as arguments. It works as data_delete but without the need of the entity being loaded prior removal.

To delete multiple entities of the same class use the data_remove_batch function.

data find

data_find takes the entity class nam as argument. If it is called without further arguments, it returns all primary keys of the corresponding persisted entities.

The second optional argument takes key value pairs with keys equal to the property names of the entity. The value of each key has to be a data value or array of data values. Key value pairs are joint via logic AND. Value arrays are interpreted as IN. Not all key value pairs or value arrays may be supported. It depends on the used infrastructure, the setting (for example the usable sql indices) and the implementation of the bridge. If one or more key value pairs are not supported a QueryException is thrown.

Instead of calling data_load_batch($fQCN, data_load($fQCN, $keyValuePairs) you can use the shorthand data_find_entities($fQCN, $keyValuePairs).

Hint: Beside this function there may be more ways to search for entities. These are not part of the earc/data abstraction.

data schedule

Server responses should be as fast as possible. To support this goal earc/data has the data_schedule function. The persisting of the supplied entity will be scheduled until data_persist is called. If you call data_persist in a shutdown function you can build and send your server response without being delayed by writing data to a database or index.

data detach

earc/data holds a reverence to each loaded entity to ensure every entity exists only once. To circumvent this behaviour data_detach can be called. It deletes the reverence.

data_detach without arguments will delete all reverences. data_detach with a class name as argument will delete all reverences to entities of this class. data_detach called with class name and primary key deletes the reverence to only one entity.

There are three reasons for calling data_detach:

  1. Changing the primary key without deleting the entity first.
  2. Generating different instances from the same data.
  3. Garbage collection.

Hint: If you change the primary key of a persisted entity without calling data_detach first you may encounter unexpected behaviour.

livecycle events

There are six livecycle events. They are represented by six interfaces (PreLoadInterface, PostLoadInterface, PrePersistInterface, PostPersistInterface, PreRemoveInterface, PostRemoveInterface). Each event exists as entity event and as service event. The service event is triggered prior the entity event. The interface method of the registered services are called every time the event is triggered, the interface methods of the entity only if the entity is affected by the event.

Any interface method will be called with the entity (if the method is not static) or class name and primary key (if the method is static). Returns are not evaluated, thus all interface methods have void return types.

via entity

To use the livecycle events via an entity, the entity has to implement the corresponding interface.

Use cases are wakeup/sleep procedures or cascading removals/persistence.

A cascade persist can be implemented as follows:

An implementation via a referenced service method and attributes might be more structured but also a bit slower. earc/data gives you the freedom to shape it for your needs or use third party plugins if available.

via service

Warning: Use service events only if you really need to process events globally, or your application is slowed down unnecessarily.

autogenerate keys

On pure and immutable entities implementing the AutoPrimaryKeyInterface the primary keys will be set automatically, if persist_entity is called without the entities having proper primary keys.

To handle key generation there exists the OnAutoPrimaryKeyInterface. Every class tagged with di_tag by this interface name will be called upon via di_get (see earc/di for further reference). It has to implement the OnAutoPrimaryKeyInterface as well. The callables received this way will be called (with the entity as argument) until a string is returned. This string is set as primary key.

You are completely in charge and responsible for key generation. You can use for example attribute driven libraries or write your own generators. Some bridges may handle this too.

bridges

earc/data is an abstraction layer. It is responsible for two major apis: 1. It is an api you call to save/load and in a restricted way find your entities, without bothering about the persisting media (filesystem, databases, memory, search indexes, etc.). 2. It is an api where the persisting infrastructure plugs in.

It was all about the first api until now. The bridges chapter is about the second api. It tells you how to plug in the persisting infrastructure.

There are five livecycle events that call upon the persisting media, each have a tag and an interface:

Any library implementing this five interfaces is a valid bridge for earc/data.

Some library will only implement a subset. Think of a search index. Only the data persist/remove/find events are relevant for it.

There exist some prebuild bridges:

plug in a bridge

To activate a bridge you have to tag the interfaces.

You can register as many services as you like. The order of tagging is the order they will be called.

Tagging has to be done after initializing the dependency injection component earc/di and before calling any data_* function.

You can skip initializing earc/di, if you initialize earc/data first.

This will init earc/di as well.

advanced usage

immutable entities

Immutable entities are a special case of pure entities. They implement the ImmutableEntityInterface. Immutable entities can not be updated and only deleted with the force flag.

If immutable entities implement the AutoPrimaryKeyInterface a new primary key will be generated on persist, if there is a data set with this primary key already.

mutable references

A common use case for immutable entities is to track the changes of a common entity by a chain of immutables. You cannot reference the entity represented by the chain via the primary key as every immutable entity has its own primary key. You cannot use another key either, because you can not remove it from the older immutables. You may attach a counter and search for the maximal value, but that may slow down entity loading significantly as the chain grows.

The solution is a second mutable entity which keeps track of the chain of immutables and updates its reverence. It can be a bit laborious and error-prone to manage this in your code. By implementing the MutableReverenceKeyInterface in the immutable entity the update of the mutable entity (which has to implement the MutableEntityReferenceInterface) is done automatically by earc/data.

There are two restriction on this concept:

  1. The mutable entity has to have a primary key, when the mutable reverence from the immutable to the mutable is established.
  2. There can only be one mutable reference entity. If you need more references from other entities to the immutable, they have to use the mutable reference entity as proxy.

To implement a mutable reference between two immutable entity chains you can use the GenericMutableEntityReference as link between them.

writing your own bridge

If there is no bridge available for your persistence infrastructure, or you need maximal control of the persisting process, you can write your own bridge.

For writing a bridge all you have to do is to implement the interfaces for the data persist/load/remove/find and primary key generation events.

on data persist

The onPersist() method of the OnPersistInterface will be called with the entities to persist as argument. Persistence must not fail silently.

on data load

The onLoad() method of the OnLoadInterface will be called with fully qualified class name and the primary keys of the entities as arguments. It has to return the entity objects on success. If the entity could not be found the callable must not throw an error, but simply not return it. Other services may return the entity object thereafter.

The interface passes as third argument an array of callables. If a service fails to load an entity, it can add a callback to the array. The callables will be called when all entities are loaded, with the entities as argument. Thus, a cache can save missing entities, without the need to listen at every post load event.

on data remove

The onRemove() method of the OnReturnInterface will be called with fully qualified class name and the primary keys of the entities as arguments. Removing an entity must not fail silently unless it has not existed yet.

on data find

The onFind() method of the OnFindInterface will be called with fully qualified class name and key-value-pairs of the entity as arguments. It has to return an array of primary keys. It may be empty if no entity fits to the key-value-pairs. They have to return null, if they cannot process the key-value-pairs because of the infrastructure or missing data, but they have to throw an earc/data QueryExceptionInterface if just a configuration or index is missing.

The empty key-value-pairs array witch has to return all existing primary keys of the entity class has to be supported always. The other key-value-pairs may not be supported or depend on configuration or indices.

Key value pairs have to be joint via logic AND. Value arrays have to be interpreted as IN.

For example callable(User::class, ['firstname' => 'Max', 'age' => [18, 19, 20, 21, 22, 23]) has to return all users with first name Max and age between 18 and 23.

Bridges may extend this syntax to support a wider range of search requests.

on primary key generation

The onAutoPrimaryKey() method of the OnAutoPrimaryKeyInterface will be called with the entity in need for a new primary key as argument. It has to return a string, or null if it is not willing to process the request.

The key generation is called upon before saving the entity. This may be a contradiction to the infrastructure, for example if the entity is persisted to a sql database which generates the key. In these cases the method has to return an empty string. Of course this must be recognised by the on data persist services.

releases

release 0.0.1

release 0.0


All versions of data with dependencies

PHP Build Version
Package Version
Requires php Version ^8.0
earc/di Version ^3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package earc/data contains the following files

Loading the files please wait ....