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: app/pages/6.0/02.background/01.introduction/docs.md
+5-6Lines changed: 5 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,24 +1,23 @@
1
1
---
2
2
title: Introduction
3
3
description: The PHP community has evolved considerably over the past decade, and this breakneck pace has caused a lot of people to get left behind. UserFrosting aims to help new and legacy developers navigate the overwhelming ocean of tools, packages, and concepts in PHP and the modern web development community as a whole.
4
-
obsolete: true
5
4
---
6
5
7
6
## Motivation
8
7
9
-
The PHP community has evolved considerably over the past decade, beginning with PHP5's support for object-oriented programming in 2006, to the first meetings of [PHP-FIG](http://www.php-fig.org/) to develop a [set of standards for PHP code](http://www.phptherightway.com/#code_style_guide), to the release of Composer as the _de facto_ package manager in 2012. At the same time the web development community as a whole has been changing, with websites becoming more dependent on Javascript and CSS to provide sophisticated client-side features. And Javascript has moved even faster!
8
+
The PHP community has evolved considerably over the past two decades, beginning with PHP 5's support for object-oriented programming in 2004, to the first meetings of [PHP-FIG](http://www.php-fig.org/) to develop a [set of standards for PHP code](http://www.phptherightway.com/#code_style_guide), to the release of Composer as the _de facto_ package manager in 2012. At the same time, the web development community as a whole has been changing, with websites becoming more dependent on JavaScript and CSS to provide sophisticated client-side features. And JavaScript has moved even faster!
10
9
11
-
This breakneck pace has caused a lot of people to get left behind. For someone who hasn't been doing web development continuously for the past ten years, it can feel like a hopeless task to try and get acquainted with all of the new tools and frameworks that seem to be coming out every day. Relevant comic from [Abstruse Goose](http://abstrusegoose.com/503):
10
+
This breakneck pace has caused a lot of people to get left behind. For someone who hasn't been doing web development continuously for the past decade or more, it can feel like an overwhelming task to get acquainted with all of the new tools and frameworks that seem to be coming out every day. Relevant comic from [Abstruse Goose](http://abstrusegoose.com/503):
12
11
13
-

12
+

14
13
15
-
The problem is that when you're a busy developer with a lot of Real-Life (tm) projects to work on, it's very difficult to set aside time to read a book about technology X - especially when you're not even sure that you really _need_ to learn X!
14
+
The problem is that when you're a busy developer with real-world projects to work on, it's very difficult to set aside time to read a book about technology X - especially when you're not even sure that you really _need_ to learn X!
16
15
17
16
UserFrosting has a better idea. Instead of learning about these technologies as a purely academic exercise, you'll work on one of _your_ projects, and learn what you need as you go!
18
17
19
18
## What exactly will I learn?
20
19
21
-
There are three main categories that UserFrosting attempts to cover: software architecture, tools of the trade, and best practices. Most of the PHP developers we see in chat or on Stack Overflow are behind in at least one these areas:
20
+
There are three main categories that UserFrosting attempts to cover: software architecture, tools of the trade, and best practices. Most of the PHP developers we see in chat or on Stack Overflow are behind in at least one of these areas:
description: "UserFrosting has a not-so-secret ulterior motive: to get you to become a better developer."
4
-
obsolete: true
5
4
---
6
5
7
6
#### Chapter 2
@@ -10,4 +9,4 @@ obsolete: true
10
9
11
10
UserFrosting has a not-so-secret ulterior motive: **to get you to become a better developer**.
12
11
13
-
In this chapter, we'll talk about the state of modern web development tools and practices, and clear up some common misconceptions about how web applications actually work. Then, we'll go over key security concepts. Finally, we'll discuss best practices to make sure that users will be able to find and use your application when it's finished.
12
+
In this chapter, we'll talk about the state of modern web development tools and practices, and clear up some common misconceptions about how web applications actually work. Then, we'll go over key security concepts. Finally, we'll discuss best practices to make sure that users will be able to find and use your application when it's finished.
Copy file name to clipboardExpand all lines: app/pages/6.0/07.dependency-injection/01.concept/docs.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -62,7 +62,7 @@ $owl1 = new Owl($nest);
62
62
$owl2 = new Owl($improvedNest);
63
63
```
64
64
65
-
But how can an owl be sure it's receiving a *nest*, and not a *dog house*? That's where **Interfaces**comes into play. If both `Nest` and `ImprovedNest`implements a `NestInterface`Interface, then the *Owl* can be sure it will receive the proper object :
65
+
But how can an owl be sure it's receiving a *nest*, and not a *dog house*? That's where **Interfaces**come into play. If both `Nest` and `ImprovedNest`implement a `NestInterface`interface, then the *Owl* can be sure it will receive the proper object:
66
66
67
67
```php
68
68
interface NestInterface
@@ -97,16 +97,16 @@ class Owl
97
97
98
98
public function getNestSize(): string
99
99
{
100
-
$this->nest->getSize();
100
+
return $this->nest->getSize();
101
101
}
102
102
}
103
103
```
104
104
105
-
In the above example, it doesn't matter if `Owl`received a `Nest` or an `ImprovedNest`, or even a `SuperDuperNest`, as long as they all obey the same definition defined by the `NestInterface`. Moreover, the Owl class can confidently call the `getSize` method of the injected `$nest` property, because the interface makes sure that method is available, no matter which implementation of the `NestInterface` it receives.
105
+
In the above example, it doesn't matter if `Owl`receives a `Nest` or an `ImprovedNest`, or even a `SuperDuperNest`, as long as they all obey the same contract defined by the `NestInterface`. Moreover, the `Owl` class can confidently call the `getSize()` method of the injected `$nest` property, because the interface ensures that method is available, no matter which implementation of the `NestInterface` it receives.
106
106
107
-
Using interfaces to declare what kind of object a class is expected to receive, even if you don't plan to have multiple "nest" types, is a key element in *Autowiring* that we'll see shortly.
107
+
Using interfaces to declare what kind of object a class is expected to receive, even if you don't plan to have multiple "nest" types, is a key element in *autowiring* that we'll see shortly.
108
108
109
109
This is of course a contrived example, but the general strategy of keeping your classes loosely coupled is a good way to make your code more reusable and easily tested.
110
110
111
111
> [!TIP]
112
-
> You can learn more, and see other examples, on the [PHP-DI Website: Understanding Dependency Injection](https://php-di.org/doc/understanding-di.html).
112
+
> You can learn more, and see other examples, on the [PHP-DI Website: Understanding Dependency Injection](https://php-di.org/doc/understanding-di.html).
Copy file name to clipboardExpand all lines: app/pages/6.0/07.dependency-injection/04.adding-services/docs.md
+8-9Lines changed: 8 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,9 +6,9 @@ obsolete: true
6
6
7
7
You'll probably want to create your own services to modularize certain aspects of your own project. For example, if your application needs to interact with some third-party API like Google Maps, you might create a `MapBuilder` class that encapsulates all of that functionality. This is a cleaner and more manageable alternative to simply stuffing all of your code directly into your controller classes.
8
8
9
-
If you want to use a single instance of `MapBuilder` throughout your application, you'll probably end up defining it as a service. To do this, you'll need to create a new `MapBuilderService` class in your site sprinkle and register it in your [Sprinkle Recipe](sprinkles/recipe#services).
9
+
If you want to use a single instance of `MapBuilder` throughout your application, you'll probably end up defining it as a service. To do this, you'll need to create a new `MapBuilderService` class in your site sprinkle and register it in your [Sprinkle Recipe](sprinkles/recipe#services).
10
10
11
-
You can actually create one big service provider for all your services, but it's best to create different provider classes for each service. This makes it easier to test and debug each of your services. It also makes things easier if you need to extend or disable a service in another sprinkle down the road. With this setup, each service resides in its own provider class instead of the global `ServiceProvider` class. For example:
11
+
You can actually create one big service provider for all your services, but it's best to create different provider classes for each service. This makes it easier to test and debug each of your services. It also makes things easier if you need to extend or disable a service in another sprinkle down the road. With this setup, each service resides in its own provider class instead of the global `ServiceProvider` class. For example:
12
12
13
13
```
14
14
app
@@ -23,7 +23,7 @@ app
23
23
24
24
First, we'll create the service class. This class **must** implement the `UserFrosting\ServicesProvider\ServicesProviderInterface` interface. It must contain the `register` method, which returns an array of [service definitions](dependency-injection/the-di-container#service-providers-definitions).
@@ -41,12 +41,12 @@ use UserFrosting\Sprinkle\Site\GoogleMaps\MapBuilder;
41
41
*/
42
42
class MapBuilderService implements ServicesProviderInterface
43
43
{
44
-
public function register(): array
44
+
public function register(): array
45
45
{
46
46
return [
47
47
MapBuilder::class => function () {
48
48
// Do what you need before building the object
49
-
...
49
+
// ...
50
50
51
51
// Now, actually build the object
52
52
$mapBuilder = new MapBuilder(...);
@@ -61,10 +61,9 @@ class MapBuilderService implements ServicesProviderInterface
61
61
> [!TIP]
62
62
> You'll notice that we've added `use UserFrosting\Sprinkle\Site\GoogleMaps\MapBuilder;` to the top of the file. This means that we don't have to use the fully qualified class name (with the entire namespace) every time we want to refer to the `MapBuilder` class.
63
63
64
-
If you need to pull in another service, for example the config to retrieve an API key, you can add them as the parameter, and the dependency injector will automatically pick it up.
64
+
If you need to pull in another service, for example the config to retrieve an API key, you can add it as a parameter, and the dependency injector will automatically pick it up.
65
65
66
66
```php
67
-
...
68
67
MapBuilder::class => function (Config $config) {
69
68
$apiKey = $config['api.key'];
70
69
@@ -73,14 +72,14 @@ MapBuilder::class => function (Config $config) {
73
72
74
73
return $mapBuilder;
75
74
},
76
-
...
77
75
```
78
76
79
77
### Register your service
80
78
81
79
The next step is to tell UserFrosting to load your service in your [Sprinkle Recipe](sprinkles/recipe#getservices). To do so, you only need to list all the service providers you want to automatically register inside the `$getServices` property of your sprinkle class :
0 commit comments