Download the PHP package webinarium/php-properties without Composer
On this page you can find all versions of the php package webinarium/php-properties. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download webinarium/php-properties
More information about webinarium/php-properties
Files in webinarium/php-properties
Package php-properties
Short Description Automatic properties implementation for PHP
License MIT
Homepage https://github.com/webinarium/php-properties
Informations about the package php-properties
Automatic properties implementation for PHP
Tl;dr
The library provides few helper traits:
- to simulate automatic/custom properties as they are defined in C#,
- to simulate object initialization on creation as it works in C#.
Installation
The recommended way to install is via Composer:
The Problem
Let's assume we need a class to represent a user's entity (quite popular case in the webdev world). The class must provide read-only ID, writeable first and last names, and a helper function to get the full name compound from the first and last ones:
Only three properties and one extra function to get the full name, but our class is already bloated with a lot of getters and setters.
Meanwhile in C# the same class could be implemented as following:
Nice and easy - even if you don't know C# you still understand what this code says. How can we get the same in PHP?
Magic methods
Of course, the first thought is magic methods, so we can rewrite the class as following:
Well, it works, but it takes nearly the same amount of code as the original class. Assume more properties, where some are read-only as Id
and some a "virtual" as fullName
and you will end up with long switch
operators in all three magic functions. Also, I bet your IDE doesn't autocomplete these properties, so we have to append the class with @property
annotations.
Annotations
We can't change the PHP syntax, but we still can extend it using annotations. Really, if we had to write the annotations in the above example, why not reuse them instead of update all three magic functions each time we introduce a new property. And this is exactly what this library does, providing required functionality in the PropertyTrait
.
If you include the PropertyTrait
in your class, the @property
annotations become a required declaration regarding your properties. Let's refactor our class using the trait:
Maybe still not as elegant as the C# version, but much closer, isn't it?
Automatic properties
Using @property
annotation you can expose any existing protected or private property. To make a property read-only (or write-only) use a @property-read
(or @property-write
) annotation instead. If you don't specify a @property
annotation for some existing non-public property, it will remain hidden.
Custom (virtual) properties
The trait contains two protected functions - getters
and setters
- which can be overridden in your class. Both functions return associated array of anonymous functions, and keys of the array are names of your virtual properties.
Let's assume we want to store some user-specific settings like user's language and user's timezone. We might have a lot of such configuration options and we don't want to bloat the related database table with the same amount of columns, while all these settings can be stored in a single settings
array:
Actually, you can provide your custom getters and setters via the getters
/setters
functions for existing property, too. In this case you will override the default behaviour of the property.
Performance
Annotations are expensive. To work around this the trait caches parsed annotations in memory, so they are parsed only once (per web-request). Below is a table of few benchmarks for different ways to work with class properties. Each number is amount of seconds which took to read a property 100000 (one hundred thousand) times. Numbers are calculated from 5 sequental runs.
Method to read a property | Min time | Avg time | Max time |
---|---|---|---|
Direct access to public property | 0.007 | 0.008 | 0.009 |
Classic getter | 0.065 | 0.066 | 0.067 |
Magic __get function |
0.073 | 0.074 | 0.075 |
Using PropertyTrait |
0.173 | 0.175 | 0.177 |
Object initialization on creation
Another nice C# feature lets you initialize object properties when you're creating the object. Taking the same User
class from above you can create and setup new object in a classic way:
or initialize the properties on creation:
The library provides another trait - DataTransferObjectTrait
- to simulate such initialization. Assume we used this trait in our User
PHP class, then new object can be created as following:
The trait defines a default constructor which takes a single array
argument. This is an associated array, where keys are names of the properties to initialize. If a property is not found for some of the keys, it will be just skipped.