You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/best-practices/controllers.md
+78-2Lines changed: 78 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,6 @@
1
-
# Controller classes to structure your app
1
+
# Controller classes
2
+
3
+
## First steps
2
4
3
5
When starting with X, it's often easiest to start with simple closure definitions like suggested in the [quickstart guide](../getting-started/quickstart.md).
4
6
@@ -113,6 +115,8 @@ class UserController
113
115
}
114
116
```
115
117
118
+
## Composer autoloading
119
+
116
120
Doesn't look too complex, right? Now, we only need to tell Composer's autoloader
117
121
about our vendor namespace `Acme\Todo` in the `src/` folder. Make sure to include
118
122
the following lines in your `composer.json` file:
@@ -142,11 +146,83 @@ assured this is the only time you have to worry about this, new classes can
142
146
simply be added without having to run Composer again.
143
147
144
148
Again, let's see our web application still works by using your favorite
145
-
webbrowser or commandline tool:
149
+
web browser or command-line tool:
146
150
147
151
```bash
148
152
$ curl http://localhost:8080/
149
153
Hello wörld!
150
154
```
151
155
152
156
If everything works as expected, we can continue with writing our first tests to automate this.
157
+
158
+
## Container
159
+
160
+
X has a powerful, built-in dependency injection container (DI container or DIC).
161
+
It allows you to automatically create request handler classes and their
162
+
dependencies with zero configuration for most common use cases.
163
+
164
+
> ℹ️ **Dependency Injection (DI)**
165
+
>
166
+
> Dependency injection (DI) is a technique in which an object receives other
167
+
> objects that it depends on, rather than creating these dependencies within its
168
+
> class. In its most basic form, this means creating all required object
169
+
> dependencies upfront and manually injecting them into the controller class.
170
+
> This can be done manually or you can use the optional container which does
171
+
> this for you.
172
+
173
+
### Autowiring
174
+
175
+
To use autowiring, simply pass in the class name of your request handler classes
@@ -1068,19 +1077,81 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp
1068
1077
1069
1078
$this->assertStringContainsString("<title>Error 500: Internal Server Error</title>\n", (string) $response->getBody());
1070
1079
$this->assertStringContainsString("<p>The requested page failed to load, please try again later.</p>\n", (string) $response->getBody());
1071
-
$this->assertStringMatchesFormat("%a<p>Expected request handler to return <code>Psr\Http\Message\ResponseInterface</code> but got uncaught <code>BadMethodCallException</code> with message <code>Unable to load request handler class \"UnknownClass\"</code> in <code title=\"See %s\">RouteHandler.php:%d</code>.</p>\n%a", (string) $response->getBody());
1080
+
$this->assertStringMatchesFormat("%a<p>Expected request handler to return <code>Psr\Http\Message\ResponseInterface</code> but got uncaught <code>BadMethodCallException</code> with message <code>Request handler class UnknownClass not found</code> in <code title=\"See %s\">RouteHandler.php:%d</code>.</p>\n%a", (string) $response->getBody());
@@ -1097,7 +1168,7 @@ public function __construct(int $value) { }
1097
1168
1098
1169
$this->assertStringContainsString("<title>Error 500: Internal Server Error</title>\n", (string) $response->getBody());
1099
1170
$this->assertStringContainsString("<p>The requested page failed to load, please try again later.</p>\n", (string) $response->getBody());
1100
-
$this->assertStringMatchesFormat("%a<p>Expected request handler to return <code>Psr\Http\Message\ResponseInterface</code> but got uncaught <code>BadMethodCallException</code> with message <code>Unable to instantiate request handler class\"%s\": %s</code> in <code title=\"See %s\">RouteHandler.php:%d</code>.</p>\n%a", (string) $response->getBody());
1171
+
$this->assertStringMatchesFormat("%a<p>Expected request handler to return <code>Psr\Http\Message\ResponseInterface</code> but got uncaught <code>BadMethodCallException</code> with message <code>Request handler class " . addslashes($class) . " failed to load: $error</code> in <code title=\"See %s\">RouteHandler.php:%d</code>.</p>\n%a", (string) $response->getBody());
@@ -1153,7 +1223,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp
1153
1223
1154
1224
$this->assertStringContainsString("<title>Error 500: Internal Server Error</title>\n", (string) $response->getBody());
1155
1225
$this->assertStringContainsString("<p>The requested page failed to load, please try again later.</p>\n", (string) $response->getBody());
1156
-
$this->assertStringMatchesFormat("%a<p>Expected request handler to return <code>Psr\Http\Message\ResponseInterface</code> but got uncaught <code>BadMethodCallException</code> with message <code>Unable to use request handler class \"%s\" because it has no \"public function __invoke()\"</code> in <code title=\"See %s\">RouteHandler.php:%d</code>.</p>\n%a", (string) $response->getBody());
1226
+
$this->assertStringMatchesFormat("%a<p>Expected request handler to return <code>Psr\Http\Message\ResponseInterface</code> but got uncaught <code>BadMethodCallException</code> with message <code>Request handler class %s has no public __invoke() method</code> in <code title=\"See %s\">RouteHandler.php:%d</code>.</p>\n%a", (string) $response->getBody());
0 commit comments