Ik ben wat aan het puzzelen met een wat groter/abstracter knutselproject. Ik maak gebruik van abstracte classes en interfaces, en de uiteindelijke class methods returnen allemaal een subtype (SomeEntity) van de abstracte Entity class.
Daardoor werkt alleen de code completion niet meer in PHP Storm
Voorbeeldje:
In dit geval geeft $customer een CustomerEntity terug. De get() method op de CustomersResource geeft dat als return type aan. Echter, de CustomersResource extent de parent abstract Resource class, en die definieert dat deze get() method een Entity moeten teruggeven.
Ik kan dus nu niet meer zien wat de properties en method van $customer zijn, omdat ik alleen gegevens van de abstracte Entity terugkrijg.
Klinkt wellicht vaag, daarom een zo concreet mogelijke sample:
Ik weet niet of het überhaupt mogelijk is om dit te realiseren omdat het abstractieniveau vrij ver gaat, maar het is wel een beetje een gemis. Het definiëren van methods en properties via PHPDoc in de Entity class is dus helaas niet mogelijk, want elke entity heeft zijn eigen gegevens
Weten jullie hier raad mee? Of is dit gewoon een kansloze missie?
Daardoor werkt alleen de code completion niet meer in PHP Storm
PHP:
1
2
3
4
5
| $factory = new ExternalServiceFactory(); $serviceClient = $factory->create('ExternalServiceABC'); $customer = $serviceClient->customers(1234)->get(); // $customer->....??? |
In dit geval geeft $customer een CustomerEntity terug. De get() method op de CustomersResource geeft dat als return type aan. Echter, de CustomersResource extent de parent abstract Resource class, en die definieert dat deze get() method een Entity moeten teruggeven.
Ik kan dus nu niet meer zien wat de properties en method van $customer zijn, omdat ik alleen gegevens van de abstracte Entity terugkrijg.
Klinkt wellicht vaag, daarom een zo concreet mogelijke sample:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| interface ExternalServiceInterface { // Returning a type of Resource public function customers($id=null): Resource; public function books($id=null): Resource; } abstract class Resource { // Returning a type of Entity public abstract function get(): Entity; public abstract function create(): Entity; public abstract function update(): Entity; public abstract function delete(): Entity; } abstract class Entity { // Some Shared entity logic.... } class CustomerEntity extends Entity { // Customer data..... } class BookEntity extends Entity { // Other data, specific for books..... } class CustomersResource extends Resource { public function get(): CustomerEntity // CustomerEntity extends abstract class Entity { return new CustomerEntity(1234, 'Robert', 'Kelly', 'r.kelly@gmail.com'); } } class BooksResource extends Resource { public function get(): BookEntity // BookEntity extends abstract class Entity { return new BookEntity(567, 'Some fictional book', 'Dan Brown', 'ISO4855485'); } } class AdapterForExternalServiceABC implements ExternalServiceInterface { public SomeExternalService $gateway; public function __construct() { $this->gateway = new SomeExternalService( getenv('API_TOKEN') ); } public function customers($id=null): CustomersResource { return new CustomersResource($this, $id); } public function books($id=null): BooksResource { return new BooksResource($this, $id); } } |
Ik weet niet of het überhaupt mogelijk is om dit te realiseren omdat het abstractieniveau vrij ver gaat, maar het is wel een beetje een gemis. Het definiëren van methods en properties via PHPDoc in de Entity class is dus helaas niet mogelijk, want elke entity heeft zijn eigen gegevens
Weten jullie hier raad mee? Of is dit gewoon een kansloze missie?