{"id":15640261,"url":"https://github.com/serafimarts/properties","last_synced_at":"2025-08-21T11:33:05.658Z","repository":{"id":62542322,"uuid":"56236822","full_name":"SerafimArts/Properties","owner":"SerafimArts","description":"PHP properties implementation","archived":false,"fork":false,"pushed_at":"2018-11-22T14:10:08.000Z","size":103,"stargazers_count":78,"open_issues_count":2,"forks_count":4,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-12-10T07:55:35.046Z","etag":null,"topics":["dsl","getters","php","phpdoc","properties","setters"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SerafimArts.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-14T12:49:00.000Z","updated_at":"2024-11-29T19:14:38.000Z","dependencies_parsed_at":"2022-11-02T16:00:37.764Z","dependency_job_id":null,"html_url":"https://github.com/SerafimArts/Properties","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SerafimArts%2FProperties","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SerafimArts%2FProperties/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SerafimArts%2FProperties/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SerafimArts%2FProperties/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SerafimArts","download_url":"https://codeload.github.com/SerafimArts/Properties/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230511479,"owners_count":18237657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dsl","getters","php","phpdoc","properties","setters"],"created_at":"2024-10-03T11:33:20.345Z","updated_at":"2024-12-19T23:13:39.609Z","avatar_url":"https://github.com/SerafimArts.png","language":"PHP","readme":"PHP Properties\n==========\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.org/SerafimArts/Properties\"\u003e\u003cimg src=\"https://travis-ci.org/SerafimArts/Properties.svg?branch=master\" alt=\"Travis CI\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://scrutinizer-ci.com/g/SerafimArts/Properties/?branch=master\"\u003e\u003cimg src=\"https://scrutinizer-ci.com/g/SerafimArts/Properties/badges/quality-score.png?b=master\" alt=\"Scrutinizer CI\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/serafim/properties\"\u003e\u003cimg src=\"https://poser.pugx.org/serafim/properties/version\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/serafim/properties\"\u003e\u003cimg src=\"https://poser.pugx.org/serafim/properties/v/unstable\" alt=\"Latest Unstable Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://raw.githubusercontent.com/serafim/properties/master/LICENSE.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\" alt=\"License MIT\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/serafim/properties\"\u003e\u003cimg src=\"https://poser.pugx.org/serafim/properties/downloads\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nPHP Properties implementations based on getters or setters method and used \n[PSR-5 PHPDoc](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md) information.\n\n- [Installation](#installation)\n- [Introduction](#introduction)\n- [Properties Usage](#properties-usage)\n    - [Readonly Properties](#readonly-properties)\n    - [Writeonly Properties](#writeonly-properties)\n    - [Getters And Setters](#getters-and-setters)\n    - [Autocomplete](#autocomplete)\n- [Type Hints](#type-hints)\n    - [Primitive Type Hints](#primitive-type-hints)\n    - [Arrays And Generics](#arrays-and-generics)\n    - [Conjunction And Disjunction](#conjunction-and-disjunction)\n- [Production Mode](#production-mode)\n\n\n## Installation\n\n`composer require serafim/properties`\n\n[Package on packagist.org](https://packagist.org/packages/serafim/properties)\n\n## Introduction\n\nProperties provide the ability to control the behavior of setting and \nretrieving data from an object fields.\n\nThere are **no properties** at the **language level**, but they can be implemented with \nthe some additional functionality. \n\nFor example:\n\n```php\nclass MyClass\n{\n    protected $a = 23;\n\n    public function __get($field)\n    {\n        return $this-\u003e$field;\n    }\n}\n\n$dto = new MyClass();\necho $dto-\u003ea; // 23\n$dto-\u003ea = 42; // Cannot access protected property MyClass::$a\n```\n\nThis code example does not provide type-hint and autocomplete. \nUsing magic without the ability to control it is always a bad option. \n...well, it looks awful %)\n\nWe can fix some problems using PSR-5. In this case, we can add a docblock.\n\n```php\n/**\n * @property-read int $a\n */\nclass MyClass\n{\n    // ...\n```\n\nBut this docblock only adds information for the IDE and does not \naffect the code itself. At the same time, you should always keep it up to date.\n\nBut wait! We have another problem.\n\n```php\n$dto = new MyClass();\necho isset($dto-\u003ea); // false\n```\n\nThis is obviously a bug. We still need to add `__isset`, `__unset` and `__set` support.\n\nIt's damn awful!!111\n\n## Properties Usage\n\nNow let's see what the `serafim/properties` package provides.\n\n```php\n/**\n * @property $a\n */\nclass MyClass\n{\n    use Serafim\\Properties\\Properties;\n    \n    protected $a = 23;\n}\n\n$dto = new MyClass();\n$dto-\u003ea;      // 23\n$dto-\u003ea = 42; // Ok\n$dto-\u003ea;      // 42\n```\n\n### Readonly Properties\n\nTo indicate that the type should be readonly use `@property-read` annotation.\n\n```php\n/**\n * @property-read $a\n */\nclass MyClass\n{\n    use Serafim\\Properties\\Properties;\n    \n    protected $a = 23;\n}\n\n$dto = new MyClass();\n$dto-\u003ea;      // 23\n$dto-\u003ea = 42; // Error: Property MyClass::$a is readonly\n```\n\n### Writeonly Properties\n\nTo indicate that the type should be readonly use `@property-write` annotation.\n\n```php\n/**\n * @property-write $a\n */\nclass MyClass\n{\n    use Serafim\\Properties\\Properties;\n    \n    protected $a = 23;\n}\n\n$dto = new MyClass();\n$dto-\u003ea = 42; // 42\n$dto-\u003ea;      // Error: Property MyClass::$a is writeonly\n```\n\n### Getters And Setters\n\nFor getter or setter override just declare `get[Property]` \n(`is[Property]` for `bool` values will be works too) or `set[Property]` methods.\n\n```php\n/**\n * @property-read int $a\n */\nclass MyClass\n{\n    use Serafim\\Properties\\Properties;\n    \n    protected $a = 23;\n\n    protected function getA() \n    {\n        return $this-\u003ea + 19;\n    }\n}\n\n$dto = new MyClass();\necho $dto-\u003ea; // 42 (because 23 + 19 = 42)\n$dto-\u003ea = 42; // Error: Property is read-only (@property-read doc declaration)\n```\n\nSetter:\n\n```php\n/**\n * @property-write string $anotherProperty\n */\nclass Some \n{\n   // ... \n   protected $anotherProperty = 'some';\n   \n    /**\n     * @param string $newVal\n     */\n   public function setAnotherProperty($newVal) \n   {\n       // Just example\n       if (mb_strlen($newVal) \u003e 4) {\n           throw new InvalidArgumentException('...');\n       }\n       \n       $this-\u003eanotherProperty = $newVal;\n   }\n}\n```\n\n### Autocomplete\n\nAll these annotations fully work in the IDE, including \nautocomplete and highlighting incorrect behavior.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://habrastorage.org/webt/_p/uk/uv/_pukuvt6exo-xvwyrzp2bi8u0re.png\" alt=\"IDE Autocomplete And Highlighting\" /\u003e\n\u003c/p\u003e\n\n\n## Type Hints\n\nAll properties with writeable behavior will be \"type checkable\".\n\n```php\n/**\n * @property int|null $a\n */\nclass Some\n{\n    use Serafim\\Properties\\Properties;\n    \n    protected $a; \n}\n\n//\n\n$some = new Some;\n$some-\u003ea = 23; // Ok\n$some-\u003ea = null; // Ok\n$some-\u003ea = 'string'; // Error: \"TypeError: Value for property Some::$a must be of the type int|null, string given\"\n```\n\n### Primitive Type Hints\n\n- `int` (or `integer`) - property value are integer\n- `bool` (or `boolean`) - value are boolean\n- `float` (or `double`) - value are float\n- `string` - value are string or object with `__toString` method\n- `null` (or `void`) - value are nullable\n- `resource` - value are resource\n- `object` - value can be any object \n- `mixed` - no type checking\n- `callable` - value can be string, instance of \\Closure, array with 2 args or object with `__invoke` method\n- `scalar` - value cannot be an object\n- `countable` - value can be a countable (array or object provided `Countable` interface).\n- `self` - value can be object of self class or string with name of self class\n\u003e _`self` keyword does **not available** yet: it will be supports in future_\n\n- `static` - value can be instance of self class or string whos are sublass of self \n\u003e _`static` keyword does **not available** yet: it will be supports in future_\n\n- `$this` - value can be only object instance of self class\n\u003e _`$this` keyword does **not available** yet: it will be supports in future_\n\n### Arrays And Generics\n\n- `array` - value is type of array\n- `Class[]` - value is type of array or instance of \\Traversable\n- `scalar[]` - value is type of array or instance of \\Traversable\n- `Collection\u003c\u003e` - value is type of array or instance of \"Collection\" and \\Traversable\n- `Collection\u003cT\u003e` - value is type of array or instance of \"Collection\" and \\Traversable\n- `Collection\u003cT,V\u003e`- value is type of array or instance of \"Collection\" and \\Traversable\n\n### Conjunction And Disjunction\n\n- `a|b` - means that the value must be type `(a or b)`.\n- `a\u0026b` - means that the value must be type `(a and b)`.\n- `a|b\u0026c` - means that the value must be type `(a or (b and c))`.\n\nSee more: https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md#appendix-a-types\n\n## Production Mode\n\nThe code is quite effective, but in the production mode you \nshould use caching. The package implements support for the PSR-16 standard.\n\n```php\n$driver = new Psr16CacheDriver(); // Your PSR16 cache driver implementation \n\n$properties = Serafim\\Properties\\Bootstrap::getInstance();\n$properties-\u003esetCacheDriver($driver);\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserafimarts%2Fproperties","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserafimarts%2Fproperties","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserafimarts%2Fproperties/lists"}