Skip to content

Commit 7a4a28b

Browse files
committed
Project creation: first commit.
1 parent 38843d9 commit 7a4a28b

27 files changed

+3618
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
vendor/
3+
*.cache

README.md

+278
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# PHP Simple Annotation
2+
3+
Yet another PHP annotation implementation. A simple and direct implementation without any complexity.
4+
5+
## Requirements
6+
7+
- PHP >= 7.4.*
8+
- ext-json
9+
- ext-mbstring
10+
11+
## Installation
12+
13+
```bash
14+
composer require jmacedo/php-simple-annotation
15+
```
16+
17+
## Usage
18+
19+
Consider the following class for the purpose of this documentation:
20+
21+
```php
22+
namespace Examples;
23+
24+
/**
25+
* Class MyAnnotatedClass
26+
*
27+
* @package Examples
28+
* @metadata {"PI": 3.14, "name": "The name", "genre": "The genre", "age": "The age"}
29+
* @PI 3.14
30+
* @list ['item 1', 'item 2', 'item 3']
31+
* @uselessClass true
32+
*/
33+
class MyAnnotatedClass
34+
{
35+
/**
36+
* @value 3.14
37+
* @var double
38+
* @description Math constant
39+
*/
40+
const PI = 3.14;
41+
42+
/** @var string */
43+
public $name;
44+
45+
/** @var string */
46+
protected $genre;
47+
48+
/** @var int */
49+
private $age;
50+
51+
/**
52+
* MyAnnotatedClass constructor.
53+
*
54+
* @param string $name
55+
* @param string $genre
56+
* @param int $age
57+
*/
58+
public function __construct(string $name = '', string $genre = '', int $age = 0)
59+
{
60+
$this->name = $name;
61+
$this->genre = $genre;
62+
$this->age = $age;
63+
}
64+
65+
/**
66+
* A method that says "Hello!".
67+
*
68+
* @methodName sayHello
69+
* @emptyAnnotation
70+
*/
71+
public function sayHello()
72+
{
73+
echo 'Hello!';
74+
}
75+
}
76+
```
77+
78+
You can instantiate the Annotation class in two ways:
79+
80+
- First:
81+
82+
```php
83+
use SimpleAnnotation\Annotation;
84+
use Examples\MyAnnotatedClass;
85+
86+
$annotation = new Annotation(MyAnnotatedClass::class);
87+
// Or
88+
$annotation = new Annotation('Examples\MyAnnotatedClass');
89+
```
90+
91+
- Second:
92+
93+
```php
94+
use SimpleAnnotation\Annotation;
95+
use Examples\MyAnnotatedClass;
96+
97+
$myAnnotatedClass = new MyAnnotatedClass();
98+
$annotation = new Annotation($myAnnotatedClass);
99+
```
100+
101+
To get class annotations:
102+
103+
```php
104+
$classAnnotations = $annotation->getClassAnnotations();
105+
106+
var_dump($classAnnotations);
107+
```
108+
109+
```
110+
object(SimpleAnnotation\AnnotationParsed)[6]
111+
private 'properties' =>
112+
array (size=6)
113+
'package' => string 'Examples' (length=8)
114+
'metadata' =>
115+
object(stdClass)[5]
116+
public 'PI' => float 3.14
117+
public 'name' => string 'The name' (length=8)
118+
public 'genre' => string 'The genre' (length=9)
119+
public 'age' => string 'The age' (length=7)
120+
'PI' => float 3.14
121+
'list' =>
122+
array (size=3)
123+
0 => string 'item 1' (length=6)
124+
1 => string 'item 2' (length=6)
125+
2 => string 'item 3' (length=6)
126+
'uselessClass' => boolean true
127+
'anotherStringValue' => string 'my string' (length=9)
128+
```
129+
130+
The ```AnnotationParsed``` class implements ```__get``` and ```__set``` magic methods, so to access the annotations keys, just access the properties:
131+
132+
```php
133+
echo "PI value is:" . $classAnnotations->PI;
134+
echo "PI is also available in: " . $classAnnotations->metadata->PI;
135+
```
136+
137+
To get methods annotations:
138+
139+
```php
140+
$methodsAnnotations = $annotation->getMethodsAnnotations();
141+
142+
var_dump($methodsAnnotations);
143+
```
144+
145+
```
146+
array (size=2)
147+
'__construct' =>
148+
object(SimpleAnnotation\AnnotationParsed)[9]
149+
private 'properties' =>
150+
array (size=1)
151+
'param' =>
152+
array (size=3)
153+
0 => string 'string $name' (length=12)
154+
1 => string 'string $genre' (length=13)
155+
2 => string 'int $age' (length=8)
156+
'sayHello' =>
157+
object(SimpleAnnotation\AnnotationParsed)[10]
158+
private 'properties' =>
159+
array (size=2)
160+
'methodName' => string 'sayHello' (length=8)
161+
'emptyAnnotation' => boolean true
162+
```
163+
164+
For a specific method, just pass the method name:
165+
166+
```php
167+
$sayHelloAnnotations = $annotation->getMethodsAnnotations('sayHello');
168+
169+
var_dump($sayHelloAnnotations);
170+
```
171+
172+
```
173+
object(SimpleAnnotation\AnnotationParsed)[11]
174+
private 'properties' =>
175+
array (size=2)
176+
'methodName' => string 'sayHello' (length=8)
177+
'emptyAnnotation' => boolean true
178+
```
179+
180+
To get properties annotations:
181+
182+
```php
183+
$propertiesAnnotations = $annotation->getPropertiesAnnotations();
184+
185+
var_dump($propertiesAnnotations);
186+
```
187+
188+
```
189+
array (size=3)
190+
'name' =>
191+
object(SimpleAnnotation\AnnotationParsed)[12]
192+
private 'properties' =>
193+
array (size=1)
194+
'var' => string 'string' (length=6)
195+
'genre' =>
196+
object(SimpleAnnotation\AnnotationParsed)[13]
197+
private 'properties' =>
198+
array (size=1)
199+
'var' => string 'string' (length=6)
200+
'age' =>
201+
object(SimpleAnnotation\AnnotationParsed)[14]
202+
private 'properties' =>
203+
array (size=1)
204+
'var' => string 'int' (length=3)
205+
```
206+
207+
For a specific property, just pass the property name:
208+
209+
```php
210+
$nameAnnotations = $annotation->getPropertiesAnnotations('name');
211+
212+
var_dump($nameAnnotations);
213+
```
214+
215+
```
216+
object(SimpleAnnotation\AnnotationParsed)[7]
217+
private 'properties' =>
218+
array (size=1)
219+
'var' => string 'string' (length=6)
220+
```
221+
222+
## And that's it
223+
224+
Just instantiate the ```SimpleAnnotation\Annotation``` class, call the methods and use the annotations values of the class you want to.
225+
226+
## Cache
227+
228+
By default, there is no cache in use, but there is a cache handler implemented that can be used, if you want.
229+
230+
This cache handler uses a file approach and had good results in some simple benchmarks I have made:
231+
232+
```php
233+
$annotation = new Annotation(MyAnnotatedClass::class);
234+
$start = microtime(true);
235+
for ($i = 0; $i < $numberOfTimes; $i++) {
236+
$classAnnotation = $annotation->getClassAnnotations();
237+
$methodsAnnotations = $annotation->getMethodsAnnotations();
238+
$propertiesAnnotations = $annotation->getPropertiesAnnotations();
239+
}
240+
$end = microtime(true);
241+
echo 'Time elapsed without cache: ' . ($end - $start) . "\n";
242+
243+
$cache = new SimpleAnnotation\Concerns\Cache\FileCache(__DIR__ . DIRECTORY_SEPARATOR . 'test.txt');
244+
$annotation2 = new Annotation(MyAnnotatedClass::class, $cache);
245+
$start2 = microtime(true);
246+
for ($i = 0; $i < $numberOfTimes; $i++) {
247+
$classAnnotation = $annotation2->getClassAnnotations();
248+
$methodsAnnotations = $annotation2->getMethodsAnnotations();
249+
$propertiesAnnotations = $annotation2->getPropertiesAnnotations();
250+
}
251+
$end2 = microtime(true);
252+
echo 'Time elapsed with cache: ' . ($end2 - $start2) . "\n";
253+
```
254+
255+
For ```$numberOfTimes=100```:
256+
257+
```bash
258+
Time elapsed without cache: 0.011738777160645
259+
Time elapsed with cache: 0.00053501129150391
260+
```
261+
262+
For ```$numberOfTimes=10000```:
263+
264+
```bash
265+
Time elapsed without cache: 1.1012320518494
266+
Time elapsed with cache: 0.055597066879272
267+
```
268+
269+
For ```$numberOfTimes=100000```:
270+
271+
```bash
272+
Time elapsed without cache: 11.216305971146
273+
Time elapsed with cache: 0.53948402404785
274+
```
275+
276+
The concrete implementation of ```\SimpleAnnotation\Concerns\ParsedAnnotation``` must implement the interface ```\JsonSerializable``` to the ```SimpleAnnotation\Concerns\Cache\FileCache``` implementation work well.
277+
278+
If you use the default implementation of this library, you don't have to worry about it.

composer.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "jmacedo/php-simple-annotation",
3+
"description": "Yet another PHP annotation implementation. A simple and direct implementation without any complexity.",
4+
"type": "library",
5+
"license": "MIT",
6+
"homepage": "https://github.com/jmacedo/php-simple-annotation",
7+
"keywords": ["annotation"],
8+
"authors": [
9+
{
10+
"name": "José Macedo",
11+
"email": "[email protected]",
12+
"homepage": "https://www.linkedin.com/in/zemacedo/",
13+
"role": "Developer"
14+
}
15+
],
16+
"require": {
17+
"php": "^7.4",
18+
"ext-json": "*",
19+
"ext-mbstring": "*"
20+
},
21+
"autoload": {
22+
"psr-4": {
23+
"": "src/",
24+
"Tests\\": "tests/"
25+
}
26+
},
27+
"require-dev": {
28+
"phpunit/phpunit": "^9.3"
29+
}
30+
}

0 commit comments

Comments
 (0)