From e17a687d9920e0d6ee1d4031fad19804b09f1df2 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Sun, 17 Feb 2019 21:29:29 -0600 Subject: [PATCH] Wrote two chapters for web section Also, tweaked build to allow for nested folders --- .gitignore | 1 + assets/css/site.css | 3 + assets/templates/_table_of_contents.phtml | 9 +++ chapters/web/01-http.md | 67 +++++++++++++++++++++++ chapters/web/02-http-post.md | 36 ++++++++++++ config.php | 12 ++++ src/Build.php | 9 ++- src/util/router.php | 7 ++- webpack.config.js | 2 +- 9 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 chapters/web/01-http.md create mode 100644 chapters/web/02-http-post.md diff --git a/.gitignore b/.gitignore index e66fc7e..3ec24f6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /docs /.build +/.idea diff --git a/assets/css/site.css b/assets/css/site.css index 0cbe3f6..1726644 100644 --- a/assets/css/site.css +++ b/assets/css/site.css @@ -260,6 +260,9 @@ button:hover .icon svg { .modal-content .table-of-contents { padding: 2em; } +.section-title { + margin-bottom: 0; +} .closed { display: none; } diff --git a/assets/templates/_table_of_contents.phtml b/assets/templates/_table_of_contents.phtml index 9ce3436..cb71f4e 100644 --- a/assets/templates/_table_of_contents.phtml +++ b/assets/templates/_table_of_contents.phtml @@ -4,6 +4,8 @@
  • Preface
  • Installing PHP
  • + +
    Basics
    1. Basics
    2. Variables
    3. @@ -24,5 +26,12 @@
    4. Abstract Classes
    5. Exceptions
    + +
    Web
    +
      +
    1. HTTP
    2. +
    3. HTTP POST
    4. +
    + Credits diff --git a/chapters/web/01-http.md b/chapters/web/01-http.md new file mode 100644 index 0000000..e1892ef --- /dev/null +++ b/chapters/web/01-http.md @@ -0,0 +1,67 @@ +HTTP stands for Hypertext Transfer Protocol. It is a standard for how requests and responses should be formatted for +a server and a web browser. When you open a link in your web browser, you are sending a HTTP request to a server and it +is responding with a HTTP response. The browser then takes the response, parses it and displays it to the user. + +Let us look at a HTTP request for PHP Apprentice. This is the request sent to the server from Firefox: +```http +GET /basics.html HTTP/2.0 +Host: phpapprentice.com +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate, br +Connection: keep-alive +Upgrade-Insecure-Requests: 1 +Pragma: no-cache +Cache-Control: no-cache +``` +The first line of the request tells us three things. First, the method of the request. A `GET` request tells the server +that the browser just wants to download whatever is stored at the link. The second value `/basics.html` determines +what should be loaded from `phpapprentice.com`. Finally, the third value tells the server what type of HTTP request it is. + +All of the lines below the top line are key/value pairs called headers. They give the server different pieces of information +about the client and the request to the server. For example, `Host` tells the server what website the browser is +trying to access. + +In response to the client's HTTP request, the server will respond with a HTTP response. Here is the response for the above request: +```http +HTTP/2.0 200 OK +server: GitHub.com +content-type: text/html; charset=utf-8 +last-modified: Sun, 13 Jan 2019 22:57:50 GMT +etag: W/"5c3bc26e-15a0" +access-control-allow-origin: * +expires: Mon, 18 Feb 2019 02:38:31 GMT +cache-control: max-age=600 +content-encoding: gzip +x-github-request-id: 8596:461C:46C99E:5BB366:5C6A184F +accept-ranges: bytes +date: Mon, 18 Feb 2019 03:06:02 GMT +via: 1.1 varnish +age: 52 +x-served-by: cache-fty21342-FTY +x-cache: HIT +x-cache-hits: 2 +x-timer: S1550459163.720652,VS0,VE0 +vary: Accept-Encoding +x-fastly-request-id: 00f0eec6f3037e428b8fc86742fe0f9965501a51 +content-length: 2084 + + + + +... +``` + +The top line of the response is in two parts, similar to a request. +The first part `HTTP/2.0` indicates the connection type, like the client. +The second part `200 OK` is the response code. `200` indicates a successful response. +There are many different response codes, the most famous being `404 Not Found`. + +A response will have headers as well, but they are to give the client information about the response. As you can see, +the `Content-Type` is set to `text/html`, which tells the client how to render the content of the response. + +Notice that below the list of response headers, there is also the content of the response. In this case, it is just HTML +which the browser can you use to display the page. + +HTTP requests and responses are the core of web communication. Next, we will look at a request type other than `GET`. diff --git a/chapters/web/02-http-post.md b/chapters/web/02-http-post.md new file mode 100644 index 0000000..1141a2a --- /dev/null +++ b/chapters/web/02-http-post.md @@ -0,0 +1,36 @@ +HTTP uses multiple different request types for indicating actions that should be performed on the server. The most common ones +you will use are: +- GET -> Retrieve a resource +- POST -> Create a new resource +- PUT -> Replace an entire resource +- PATCH -> Update attributes of a resource +- DELETE -> Delete a resource + +We have already seen a GET request. The next most common request type is POST. A POST request is structured the same as a GET request, however, it will contain data in the request body: +```http +POST /login.php HTTP/1.1 +Host: localhost:8080 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Referer: http://localhost:8080/login.php +Content-Type: application/x-www-form-urlencoded +Content-Length: 30 +Connection: keep-alive +Upgrade-Insecure-Requests: 1 +Pragma: no-cache +Cache-Control: no-cache + +username=php&password=password +``` +The above request is an example login request created by Firefox. You can see in the first line that POST is used to declare the request type. +At the bottom of the request, the contents contain the user's username and password. A server can easily parse the data and do something with it. In this case, it can authenticate the user. + +POST requests are used to send data to a server. A server will process the data and perform an action or store the data. + +We have been talking a lot about how a server can process requests and send responses. How do programmers develop a server to handle HTTP requests? With PHP! + +PHP was built with web server development in mind. Let us write our first PHP server script. + + diff --git a/config.php b/config.php index 59e9567..b4d3f0c 100644 --- a/config.php +++ b/config.php @@ -153,6 +153,18 @@ return [ 'title' => 'Exceptions', 'subtitle' => 'Throwing errors', 'previous' => 'abstract', + 'next' => 'web/http', + ]), + Page::create('web/http', 'web/01-http.md', [ + 'title' => 'HTTP', + 'subtitle' => 'Understanding the format of the web', + 'previous' => 'exceptions', + 'next' => 'web/http-post', + ]), + Page::create('web/http-post', 'web/02-http-post.md', [ + 'title' => 'HTTP POST', + 'subtitle' => 'Sending data to a server', + 'previous' => 'web/http', 'next' => '', ]), ], diff --git a/src/Build.php b/src/Build.php index 3d2e2ed..6c7899a 100644 --- a/src/Build.php +++ b/src/Build.php @@ -115,7 +115,14 @@ class Build } $output = $this->getOutput($template, $page->variables); - file_put_contents(config('output_dir') . '/' . $page->name . '.html', $output); + $path = config('output_dir') . '/' . $page->name . '.html'; + $dir = pathinfo($path, PATHINFO_DIRNAME); + + if (!file_exists($dir)) { + mkdir($dir, 0777, true); + } + + file_put_contents($path, $output); return $output; } diff --git a/src/util/router.php b/src/util/router.php index 04bc5a7..dcabee0 100644 --- a/src/util/router.php +++ b/src/util/router.php @@ -16,8 +16,13 @@ if ($pathinfo['dirname'] == '/' && !isset($pathinfo['extension'])) { } if ($pathinfo['extension'] == 'html') { + $name = $pathinfo['filename']; + if ($pathinfo['dirname'] != '/') { + $name = ltrim($pathinfo['dirname'], '/') . '/' . $name; + } + $build = new Apprentice\Build; - $output = $build->runSingleBuild($pathinfo['filename']); + $output = $build->runSingleBuild($name); echo $output; diff --git a/webpack.config.js b/webpack.config.js index 9e90541..1ef86b3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,7 +8,7 @@ Encore .enablePostCssLoader() .configureBabel(function (babel) { babel.plugins.push(['prismjs', { - "languages": ["php"], + "languages": ["php", "http"], "css": false, }]); })