In PHP, for storing and transferring heterogeneous data (component configurations, parameter sets for functions, options for widgets, etc.) arrays are usually used - their versatility and ease of use greatly contributes to this, but this causes the following problems:
- When developing even in advanced IDE (development systems) and when executing an application, there is no control over the structure and data types in the array.
- IDE can do nothing to help with development, so that the names of possible array keys will have to be remembered-typed or somewhere searched-copied-pasted, which, apart from inconvenience and poor performance, increases the likelihood of a typo.
- It is difficult to control where the individual elements of this array are used and, accordingly, it is difficult to refactor, even despite the power of modern IDEs.
For small projects, these problems may still be insignificant, it is easier to control everything there, but as the amount of code grows, they become more noticeable.
')
One of the well-known approaches that solves problems 2 and 3 is the creation of objects based on such pseudo-classes extending stdClass. The class properties described in PHPDoc and specifying wherever an object of its class is used (in PHPDoc) allows the autocomplete to work and check possible property names, control where properties are applied and, if necessary, easily refactor them:
class DataStorage extend stdClass { } $ds=new DataStorage; $ds->integer=13; $ds->integers=[1,2,3];
But the problem with the control of values is not solved this way, the IDE does not control the data that came from outside, not to mention that someone can ignore a warning in the IDE, as a result, incorrect data can lead to an unexpected error in an unexpected place. In addition, as far as I know, PHPDoc does not yet allow you to specify a list of possible property values, which is often important.
Add some PHP magic: StrictDataStorage
Not finding a suitable solution to these problems, I developed a class that allows you to perform data checking based on PHPDoc, while also checking the values as an additional bonus by the list of possible ones. The class works similarly to the solution given above with stdClass - a class inherited from StrictDataStorage is created and its
@property
types are described in PHPDoc via
@property
. When assigning values to properties, values are checked for compliance with the type described and by the result of the check, either an assignment occurs or an error handler is triggered — an exception is thrown by default. When checking supports all phpdoc data types except callable, the enumeration of several possible types through | and arrays described by [] at the end of the type.
In addition to the
@property
element,
@enum
and
@options
.
@enum
Allows you to specify a list of possible values for the property. The study of information available on the Internet has led to the conclusion that there is currently no standard or even an agreement on this issue, so for the time being it has come up with its own version that does not conflict with
@property
. The
@enum
syntax
@enum
similar to
@property
- first comes the description of possible values, then the name of the property. Possible values are specified in two ways.
- A list in square brackets - the contents of the brackets can be disassembled via json_decode (), therefore it should be in format, which means, first of all, the use of double quotes for framing strings.
- By the name of the class in which the values are stored, this class must support the EnumArrayableInterface interface, which lies in the same repository. In principle, SplEnum support can be made.
@options
Contains class operation settings separated by commas, currently two values are supported:
- PhpDocNotRequired - by default, if the property is not described by the
@enum
or @property
element, then it is impossible to assign a value to it, the presence of PhpDocNotRequired in @options
includes a less strict verification mode - the @options
. Property. assigned even if not described. This mode allows you to describe only those properties for which value checking is important. - StrictNumberTypeCheck - by default, if a property is described as an integer or float , then strings containing numbers are also tested, as is commonly used in PHP, adding StrictNumberTypeCheck to
@options
activates a more strict mode of checking numbers - the strings will not pass!
Example
The class StrictDataStorage is laid out here
github.com/Yannn/php-strict-data , as it works I will illustrate with the example of the successor SampleDataStorage given in the same place:
<?php class SampleDataStorage extends StrictDataStorage { }
Since specified
@options PhpDocNotRequired
for an object of the
SampleDataStorage class
you can assign a value to any property, but if you assign the properties $ integer, $ callback, $ mixed, $ integers, $ enumFloat, $ enumArray, the values will be checked according to the rules described in
@property
and
@enum
:
- The value of $ integer db. necessarily an integer, if you remove the value StrictNumberTypeCheck from
@options
, you can assign a string containing an integer. - The value of $ callback db. necessarily closure, i.e. an object of type Closure.
- The value of $ mixed m. Any - the type is not checked.
- The value of $ integers d. array of integers, while the list of possible values of the elements of the array will be obtained by the getEnumValues () method from SampleEnum .
- The value of $ enumFloat d. a fractional number or a string, with possible values listed in the list
["1.8","7","9"]
. - The value of $ enumArray should be. array of strings, while the possible values of the elements of the array are listed in the list
["one","two"]
.
If the value does not correspond to the specified rules, an exception will be raised. Methods that handle errors are implemented as protected, so that the behavior when an error is easily changed by inheritance.
Compatibility Requirements
Since I have been using PHP 5.4 for a long time, and the class requires PHP> = 5.4; there seems to be no other special requirements.
I would be happy for comments, suggestions and of course bugreports.