fix some typos
This commit is contained in:
parent
2fbbd082f2
commit
62cff766db
7 changed files with 41 additions and 41 deletions
|
@ -23,7 +23,7 @@ like this:
|
|||
},
|
||||
```
|
||||
|
||||
Now run `composer update` in your console and it will be installed.
|
||||
Now run `composer update` in your console, and it will be installed.
|
||||
|
||||
Another way to install packages is to simply type "composer require filp/whoops" into your terminal at the project root,
|
||||
i that case composer automatically installs the package and updates your composer.json-file.
|
||||
|
@ -33,7 +33,7 @@ ideally a [PSR-4](http://www.php-fig.org/psr/psr-4/) autoloader. Composer alread
|
|||
only have to add a `require __DIR__ . '/../vendor/autoload.php';` to your `Bootstrap.php`.
|
||||
|
||||
**Important:** Never show any errors in your production environment. A stack trace or even just a simple error message
|
||||
can help someone to gain access to your system. Always show a user friendly error page instead and send an email to
|
||||
can help someone to gain access to your system. Always show a user-friendly error page instead and send an email to
|
||||
yourself, write to a log or something similar. So only you can see the errors in the production environment.
|
||||
|
||||
For development that does not make sense though -- you want a nice error page. The solution is to have an environment
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
I have added some more helpers to my composer.json that help me with development. As these are scripts and programms
|
||||
used only for development they should not be used in a production environment. Composer has a specific sections in its
|
||||
file called "dev-dependencies", everything that is required in this section does not get installen in production.
|
||||
file called "dev-dependencies", everything that is required in this section does not get installed in production.
|
||||
|
||||
Let's install our dev-helpers and i will explain them one by one:
|
||||
`composer require --dev phpstan/phpstan symfony/var-dumper slevomat/coding-standard symplify/easy-coding-standard rector/rector`
|
||||
|
@ -15,7 +15,7 @@ Phpstan is a great little tool, that tries to understand your code and checks if
|
|||
create bad defined interfaces and structures. It also helps in finding logic-errors, dead code, access to array elements
|
||||
that are not (or not always) available, if-statements that always are true and a lot of other stuff.
|
||||
|
||||
A very simple example would be a small functions that takes a DateTime-Object and prints it in a human readable format.
|
||||
A very simple example would be a small functions that takes a DateTime-Object and prints it in a human-readable format.
|
||||
|
||||
```php
|
||||
/**
|
||||
|
@ -45,9 +45,9 @@ Line Bootstrap.php
|
|||
```
|
||||
|
||||
The second error is something that "declare strict-types" already catches for us, but the first error is something that
|
||||
we usually would not discover easily without speccially looking for this errortype.
|
||||
we usually would not discover easily without specially looking for this error-type.
|
||||
|
||||
We can add a simple configfile called `phpstan.neon` to our project so that we do not have to specify the errorlevel and
|
||||
We can add a simple config file called `phpstan.neon` to our project so that we do not have to specify the error level and
|
||||
path everytime we want to check our code for errors:
|
||||
|
||||
```yaml
|
||||
|
@ -59,7 +59,7 @@ parameters:
|
|||
now we can just call `./vendor/bin/phpstan analyze` and have the same setting for every developer working in our project
|
||||
|
||||
With this settings we have already a great setup to catch some errors before we execute the code, but it still allows us
|
||||
some silly things, therefore we want to add install some packages that enforce rules that are a little bit more strict.
|
||||
some silly things, therefore we want to add install some packages that enforce rules that are a little stricter.
|
||||
|
||||
```shell
|
||||
composer require --dev phpstan/extension-installer
|
||||
|
@ -67,7 +67,7 @@ composer require --dev phpstan/phpstan-strict-rules thecodingmachine/phpstan-str
|
|||
```
|
||||
|
||||
During the first install you need to allow the extension installer to actually install the extension. The second command
|
||||
installs some more strict rulesets and activates them in phpstan.
|
||||
installs some more strict rules and activates them in phpstan.
|
||||
|
||||
If we now rerun phpstan it already tells us about some errors we have made:
|
||||
|
||||
|
@ -84,9 +84,9 @@ Line Bootstrap.php
|
|||
```
|
||||
|
||||
The last two Errors are caused by the Exception we have used to test the ErrorHandler in the last chapter if we remove
|
||||
that we should be able to fix that. The first error is something we could fix, but I dont want to focus on that specific
|
||||
that we should be able to fix that. The first error is something we could fix, but I don't want to focus on that specific
|
||||
problem right now. Phpstan gives us the option to ignore some errors and handle them later. If for example we are working
|
||||
on an old legacy codebase and wanted to add static analysis to it but cant because we would get 1 Million error messages
|
||||
on an old legacy codebase and wanted to add static analysis to it but can't because we would get 1 Million error messages
|
||||
everytime we use phpstan, we could add all those errors to a list and tell phpstan to only bother us about new errors we
|
||||
are adding to our code.
|
||||
|
||||
|
@ -128,7 +128,7 @@ which basically does the same has in my experience some more Rules available tha
|
|||
But we are going to use neither of those tools directly and instead choose the [Easy Coding Standard](https://github.com/symplify/easy-coding-standard)
|
||||
which allows us to combine rules from both mentioned tools, and also claims to run much faster. You could check out the
|
||||
documentation and decide on your own coding standard. Or use the one provided by me, which is base on PSR-12 but adds
|
||||
some highly opiniated options. First create a file 'ecs.php' and either add your own configuration or copy the my
|
||||
some highly opiniated options. First create a file 'ecs.php' and either add your own configuration or copy the
|
||||
prepared one:
|
||||
|
||||
```php
|
||||
|
@ -288,8 +288,8 @@ with lots of parameters by hand all the time, so I added a few lines to my `comp
|
|||
},
|
||||
```
|
||||
|
||||
that way I can just type "composer" followed by the command name in the root of my project. if i want to start the
|
||||
php devserver I can just type "composer serve" and dont have to type in the hostname, port and targetdirectory all the
|
||||
that way I can just type "composer" followed by the command name in the root of my project. if I want to start the
|
||||
php dev server I can just type "composer serve" and don't have to type in the hostname, port and target directory all the
|
||||
time.
|
||||
|
||||
You could also configure PhpStorm to automatically run these commands in the background and highlight the violations
|
||||
|
@ -297,7 +297,7 @@ directly in the file you are currently editing. I personally am not a fan of thi
|
|||
flow when programming and always forces me to be absolutely strict even if I am only trying out an idea for debugging.
|
||||
|
||||
My workflow is to just write my code the way I currently feel and that execute the phpstan and the fix scripts before
|
||||
commiting and pushing the code. There is a [highly opiniated blogpost](https://tomasvotruba.com/blog/2019/06/24/do-you-use-php-codesniffer-and-php-cs-fixer-phpstorm-plugin-you-are-slow-and-expensive/)
|
||||
committing and pushing the code. There is a [highly opiniated blogpost](https://tomasvotruba.com/blog/2019/06/24/do-you-use-php-codesniffer-and-php-cs-fixer-phpstorm-plugin-you-are-slow-and-expensive/)
|
||||
discussing that topic further. That you can read. But in the end it boils down to what you are most comfortable with.
|
||||
|
||||
[<< previous](03-error-handler.md) | [next >>](05-http.md)
|
12
05-http.md
12
05-http.md
|
@ -19,7 +19,7 @@ the laminas/laminas-diactoros package as i am an old time fan of the laminas (pr
|
|||
Some alternatives are [slim-psr7](https://github.com/slimphp/Slim-Psr7), [Guzzle](https://github.com/guzzle/psr7) and a
|
||||
[lot more](https://packagist.org/providers/psr/http-message-implementation) are available for you to choose from.
|
||||
|
||||
Symfony ships its own Request and Response objects that do not implement the psr-7 interfaces. Therefore i will not use
|
||||
Symfony ships its own Request and Response objects that do not implement the psr-7 interfaces. Therefore, I will not use
|
||||
that in this tutorial, but if you understand how the psr-7 interfaces work you should have no problem in understanding
|
||||
the [symfony http-foundation](https://symfony.com/doc/current/components/http_foundation.html#request).
|
||||
|
||||
|
@ -38,7 +38,7 @@ $response->getBody()->write('The Uri is: ' . $request->getUri()->getPath());
|
|||
|
||||
This sets up the `Request` and `Response` objects that you can use in your other classes to get request data and send a response back to the browser.
|
||||
|
||||
In order to actually add content to the response you have to access the Body-Streamobject of the Response and use the
|
||||
In order to actually add content to the response you have to access the body stream object of the Response and use the
|
||||
write()-Method on that object.
|
||||
|
||||
|
||||
|
@ -66,7 +66,7 @@ $response = $response->withStatus(200);
|
|||
$response = $response->withAddedHeader('Content-type', 'application/json');
|
||||
```
|
||||
|
||||
If you have ever struggled with Mutationproblems in an DateTime-Object you might understand why the standard has been
|
||||
If you have ever struggled with Mutation-problems in an DateTime-Object you might understand why the standard has been
|
||||
defined this way.
|
||||
|
||||
But if you have been keeping attention you might argue that the following line should not work if the request object is
|
||||
|
@ -80,7 +80,7 @@ The response-body implements a stream interface which is immutable for some reas
|
|||
[meta-document](https://www.php-fig.org/psr/psr-7/meta/#why-are-streams-mutable). For me the important thing is to be
|
||||
aware of the problems that can occur with mutable objects. Here is a small [Blogpost](http://andrew.carterlunn.co.uk/programming/2016/05/22/psr-7-is-not-immutable.html) that gives some context. Beware that the Middleware-Example in
|
||||
the post is based on a deprecated middleware standard. But more on middlewares will be discussed in later chapters.
|
||||
I for one am happy about that fact, as it saves me from writing at least 3 lines of code whenever i want to add content
|
||||
I, for one, am happy about that fact, as it saves me from writing at least 3 lines of code whenever i want to add content
|
||||
to a response object.
|
||||
|
||||
```php
|
||||
|
@ -90,7 +90,7 @@ $response = $response->withBody($body);
|
|||
```
|
||||
|
||||
Right now we are just outputting the Response-Body without any headers or http-status. So we need to expand our
|
||||
output-logic a little bit more. Replace the line that echos the response-body with the following:
|
||||
output-logic a little more. Replace the line that echos the response-body with the following:
|
||||
|
||||
```php
|
||||
foreach ($response->getHeaders() as $name => $values) {
|
||||
|
@ -114,7 +114,7 @@ echo $response->getBody();
|
|||
```
|
||||
|
||||
This code is still fairly simple and there is a lot more stuff that can be considered when emitting a response to a
|
||||
webbrowser, if you want a more complete solution you can take a look at the [httpsoft/http-emitter](https://github.com/httpsoft/http-emitter/blob/master/src/SapiEmitter.php) package on github.
|
||||
browser, if you want a more complete solution you can take a look at the [httpsoft/http-emitter](https://github.com/httpsoft/http-emitter/blob/master/src/SapiEmitter.php) package on github.
|
||||
|
||||
Remember that the object is only storing data, so if you set multiple status codes before you send the response, only the last one will be applied.
|
||||
|
||||
|
|
|
@ -63,10 +63,10 @@ dispatcher gets called and the appropriate part of the switch statement will be
|
|||
we collect any variable parameters of the route, store them in the request parameterbag and call the handler callable.
|
||||
If the route dispatcher returns a wrong value in the first entry of the routeMatch array we handle it the same as a 404.
|
||||
|
||||
This setup might work for really small applications, but once you start adding a few routes your bootstrap file will
|
||||
This setup might work for tiny applications, but once you start adding a few routes your bootstrap file will
|
||||
quickly get cluttered. So let's move them out into a separate file.
|
||||
|
||||
Create a new directory in you projectroot named 'config' and add a 'routes.php' file with the following content;
|
||||
Create a new directory in you project root named 'config' and add a 'routes.php' file with the following content;
|
||||
|
||||
```php
|
||||
<?php declare(strict_types = 1);
|
||||
|
@ -95,7 +95,7 @@ $dispatcher = \FastRoute\simpleDispatcher($routeDefinitionCallback);
|
|||
|
||||
This is already an improvement, but now all the handler code is in the `routes.php` file. This is not optimal, so let's fix that in the next part.
|
||||
|
||||
Of course we now need to add the 'config' folder to the configuration files of our
|
||||
devhelpers so that they can scan that directory as well.
|
||||
Of course, we now need to add the 'config' folder to the configuration files of our
|
||||
dev helpers so that they can scan that directory as well.
|
||||
|
||||
[<< previous](05-http.md) | [next >>](07-dispatching-to-a-class.md)
|
||||
|
|
|
@ -33,8 +33,8 @@ final class Hello implements \Psr\Http\Server\RequestHandlerInterface
|
|||
```
|
||||
|
||||
You can see that we implement the [RequestHandlerInterface](https://github.com/php-fig/http-server-handler/blob/master/src/RequestHandlerInterface.php)
|
||||
that has a 'handle'-Method with requires a Requestobject as its parameter and returns a Responseobject. For now this is
|
||||
fine, but we may have to change our approach later. In anyway it is good to know about this interface as we will implement
|
||||
that has a 'handle'-Method with requires a Request object as its parameter and returns a Response-object. For now this is
|
||||
fine, but we may have to change our approach later. In any way it is good to know about this interface as we will implement
|
||||
it in some other parts of our application as well. In order to use that Interface we have to require it with composer:
|
||||
`composer require psr/http-server-handler`.
|
||||
|
||||
|
@ -77,9 +77,9 @@ Now if you visit `http://localhost:1235/` everything should work. If not, go bac
|
|||
And of course don't forget to commit your changes.
|
||||
|
||||
Something that still bothers me is the fact, that we do have classes for our Handlers, but the Error responses are still
|
||||
generated in the routing-matching section and not in special classes. Also we have still left some cases to chance, for
|
||||
generated in the routing-matching section and not in special classes. Also, we have still left some cases to chance, for
|
||||
example if there is an error in creating our RequestHandler class or if the call to the 'handle' function fails. We still
|
||||
have our whoopsie error-handler but i like to be more explicit in my control flow.
|
||||
have our whoopsie error-handler, but I like to be more explicit in my control flow.
|
||||
|
||||
In order to do that we need to define some special Exceptions that we can throw and catch explicitly. Lets add a new
|
||||
Folder/Namespace to our src directory called Exceptions. And define the classes NotFound, MethodNotAllowed and
|
||||
|
@ -99,7 +99,7 @@ final class NotFound extends Exception{}
|
|||
|
||||
Use that example to create a MethodNotAllowedException.php and InternalServerErrorException.php as well.
|
||||
|
||||
After you have created those we update our Routercode to use the new Exceptions.
|
||||
After you have created those we update our Router code to use the new Exceptions.
|
||||
|
||||
```php
|
||||
try {
|
||||
|
|
|
@ -7,7 +7,7 @@ want to switch to a more powerfull Http-Implementation later, or need to create
|
|||
we would need to edit every one of our request handlers to call a different constructor of the class.
|
||||
|
||||
The sane option is to use [inversion of control](http://en.wikipedia.org/wiki/Inversion_of_control). This means that
|
||||
instead of giving the class the responsiblity of creating the object it needs, you just ask for them. This is done
|
||||
instead of giving the class the responsibility of creating the object it needs, you just ask for them. This is done
|
||||
with [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection).
|
||||
|
||||
If this sounds a little complicated right now, don't worry. Just follow the tutorial and once you see how it is
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
In the last chapter we rewrote our Actions to require the response-objet as a constructor parameter, and provided it
|
||||
in the dispatcher section of our `Bootstrap.php`. As we only have one dependency this works really fine, but if we have
|
||||
different classes with different dependencies our bootstrap file gets complicated quite quickly. Lets look at an example
|
||||
different classes with different dependencies our bootstrap file gets complicated quite quickly. Let's look at an example
|
||||
to explain the problem and work on a solution.
|
||||
|
||||
#### Adding a clock service
|
||||
|
||||
Lets assume that we want to show the current time in our Hello action. We could easily just call use one of the many
|
||||
ways to get the current time directly in the handle-method, but lets create a separate class and interface for that so
|
||||
ways to get the current time directly in the handle-method, but let's create a separate class and interface for that so
|
||||
we can later configure and switch our implementation.
|
||||
|
||||
We need a new 'Service\Time' namespace, so lets first create the folder in our 'src' directory 'src/Service/Time'.
|
||||
|
@ -45,7 +45,7 @@ final class SystemClock implements Clock
|
|||
}
|
||||
```
|
||||
|
||||
Now we can require the Clockinterface as a depencency in our controller and use it to display the current time.
|
||||
Now we can require the Clock interface as a dependency in our controller and use it to display the current time.
|
||||
```php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
|
@ -82,7 +82,7 @@ final class Hello implements RequestHandlerInterface
|
|||
}
|
||||
```
|
||||
|
||||
But if we try to access the corresponding route in the webbrowser we get an error:
|
||||
But if we try to access the corresponding route in the browser we get an error:
|
||||
> Too few arguments to function Lubian\NoFramework\Action\Hello::__construct(), 1 passed in /home/lubiana/PhpstormProjects/no-framework/app/src/Bootstrap.php on line 62 and exactly 2 expected
|
||||
|
||||
Our current problem is, that we have two Actions defined, which both have different constructor requirements. That means,
|
||||
|
@ -114,7 +114,7 @@ I mostly define an Interface or a fully qualified classname as an ID. That way I
|
|||
the Clock interface or an Action class and get an object of that class or an object implementing the given Interface.
|
||||
|
||||
For the sake of this tutorial we will put a new file in our config folder that returns an anonymous class implementing
|
||||
the containerinterface.
|
||||
the container-interface.
|
||||
|
||||
In this class we will configure all services required for our application and make them accessible via the get($id)
|
||||
method.
|
||||
|
@ -164,13 +164,13 @@ return new class () implements \Psr\Container\ContainerInterface {
|
|||
};
|
||||
```
|
||||
|
||||
Here I have declared a services array, that has a class- or interfacename as the keys, and the values are short
|
||||
Here I have declared a services array, that has a class- or interface name as the keys, and the values are short
|
||||
closures that return an Object of the defined class or interface. The `has` method simply checks if the given id is
|
||||
defined in our services array, and the `get` method calls the closure defined in the array for the given id key and then
|
||||
returns the result of that closure.
|
||||
|
||||
To use the container we need to update our Bootstrap.php. Firstly we need to get an instance of our container, and then
|
||||
use that to create our Request-Object as well as the Dispatcher. So remove the manual instantion of those objects and
|
||||
use that to create our Request-Object as well as the Dispatcher. So remove the manual instantiation of those objects and
|
||||
replace that with the following code:
|
||||
|
||||
```php
|
||||
|
@ -201,7 +201,7 @@ assert($handler instanceof RequestHandlerInterface);
|
|||
|
||||
If you now open the `/hello` route in your browser everything should work again!
|
||||
|
||||
#### Using Autowiring
|
||||
#### Using Auto wiring
|
||||
|
||||
If you take a critical look at the services array you might see that we need to manually define how our Hello- and
|
||||
Other-Action are getting constructed. This is quite repetitive, as we have already declared what objects to create
|
||||
|
@ -215,9 +215,9 @@ functionality ourselves, or just try to use a library that takes care of that fo
|
|||
You can query the composer database to find all [libraries that implment the container interface](https://packagist.org/providers/psr/container-implementation).
|
||||
|
||||
I choose the [PHP-DI](https://packagist.org/packages/php-di/php-di) container, as it is easy to configure and provides some very [powerfull features](https://php-di.org/#autowiring)
|
||||
out of the box, and also solves the autowiring problem.
|
||||
out of the box, and also solves the auto wiring problem.
|
||||
|
||||
Lets rewrite our `container.php` file to use the PHP-DI container and only define the Services the Container cannot
|
||||
Let's rewrite our `container.php` file to use the PHP-DI container and only define the Services the Container cannot
|
||||
automatically build.
|
||||
|
||||
```php
|
||||
|
@ -237,7 +237,7 @@ return $builder->build();
|
|||
```
|
||||
|
||||
As the PHP-DI container that is return by the `$builder->build()` method implements the same container interface as our
|
||||
previously used ad-hoc container we won't need to update the our Bootstrap file and everything still works.
|
||||
previously used ad-hoc container we won't need to update the Bootstrap file and everything still works.
|
||||
|
||||
|
||||
[<< previous](08-inversion-of-control.md) | [next >>](10-invoker.md)
|
Loading…
Reference in a new issue