Lekce 2 - Návštěvní kniha přes WebSocket - Server a hlavní PHP třída
V minulé lekci, Návštěvní kniha přes WebSocket - Úvod a instalace nástrojů, jsme si představili a nainstalovali potřebné technologie.
Dnešní tutoriál bude věnován implementaci backendu, budeme již programovat Node.js server a základní PHP systém.
Node.js část
Náš adresář RealtimeKnihaNavstev
si otevřeme
ve vývojovém prostředí, které jsme si vybrali na začátku. Následovně si
v adresáři Nodejs vytvoříme soubor server.js.
Nodejs/server.js
V první řadě si musíme všechny moduly aktivovat.
var app = require('express')(); var http = require('http').Server(app); var bodyParser = require("body-parser"); var io = require('socket.io')(http);
Následovně si vytvoříme proměnnou port, kde zároveň zvolíme port celého Node.js souboru.
var port = 4000;
Nyní řekneme serveru na jakém portu má běžet a nastartujeme jej. Po nastartování uvedeme hlášku do konzole s tím, že server běží na portu podle proměnné.
http.listen(port, function() { console.log('Server jede na portu: ' + port); });
Nastavíme si bodyParser (abychom mohli zpracovávat POST request).
var urlencodedParser = bodyParser.urlencoded({ extended: false });
Pokračujeme přidáním dalšího kódu, který si záhy vysvětlíme.
app.post('/', urlencodedParser, function (req, res) { if (!req.body) return res.sendStatus(400); var post = req.body; if(post.password == "d$0awd6$5ZVawdIhlawdZJr8xwadtRFnSlbRX2.$2a$0awd6$5ZVIhawdlZJwdr8xtRFnS72lbRX2.Dsylt5.YSi1BzzqawdBt3rsBawdxYQMYIqsFe") { io.emit(post.channel, JSON.parse(post.data)); res.send('true'); } else { res.sendStatus(400); } });
Na začátku říkáme aplikaci, že má naslouchat POST requestu na adrese
/
(takže hned na ip/doméně). Zároveň aplikaci předáme
parser, který bude data z POST requestu parsovat na čitelnější podobu.
Dále si přidáme podmínku, zda POST obsahuje nějaká data. Pokud ne,
pošleme status 400
a vypíšeme bad request. Deklarujeme
proměnnou post, která bude obsahovat data z POST požadavku.
Nyní se dostáváme k oblasti, kdy si zvolíme naše heslo, kterým, budeme ověřovat, že daný POST odesílá opravdu náš PHP curl a ne nějaký záškodník s AJAXem. Pokud se heslo ověří, pošleme socket uživatelům s připraveními daty od PHP a vrátíme true pro PHP, protože jsme provedli co se po nás chtělo. Když se heslo neověří jako správné, pošleme status 400 a tím vypíšeme bad request.
Jako poslední krok bychom měli ošetřit situaci, kdy se uživatel jen tak připojí na Node.js přes prohlížeč. Tehdy mu vypíšeme bad request .
app.get('/', function(req, res){ res.sendStatus(400); });
Celý server nyní zapneme a vyzkoušíme jestli vše funguje. To učiníme tak, že si otevřeme příkazový řádek a do něj napíšeme příkaz:
cd <cesta do adresáře NodeJs>
(Do příkazu si vložte cestu, kterou zjistíte, když si v průzkumníku otevřete daný adresář, kliknete na cestu nahoře a zkopírujete jí). Dále již jen využijeme příkaz pro nastartování serveru:
node server.js
Pokud se v konzoli objevilo
Server jede na portu 4000
, tak je vše v pořádku.
Ještě zkusíme jít do prohlížeče a zadat do adresního políčka adresu
localhost:4000
. Měli bychom vidět text
bad request
, což je správně Server nyní můžeme vypnout a to
tak, že půjdeme zpět do příkazového řádku a Node.js proces jednoduše
ukončíme stiskem ctrl + c.
To je vše z části Node.js. Node nám nyní bude krásně přeposílat data, která získá z POST requestu, uživatelům do prohlížeče. Ta dále zpracujeme a tím docílíme okamžitého přidávání nových příspěvků do knihy.
PHP část
Vrhněme se na PHP část, kde jsem si připravil jednoduchý systém.
Zaprvé si musíme Apache přenastavit tak, aby jako kořenový adresář bral
náš PHP adresář. Otevřeme si XAMPP Control Panel a tam klikneme na
tlačítko Config
u položky Apache. V nabídce vybereme první
položku (httpd.conf).
Najdeme řádek 244 a 245 (pokud máte stejnou verzi jako já, případně hledejte podle náhledu níže), document root přenastavíme na cestu k našemu PHP adresáři, stejně tak Directory. V mém případě řádky vypadají takto:
DocumentRoot "C:\Users\patrik\Documents\ITnetwork\Tvorba\RealtimeKnihaNavstev\Code\PHP" <Directory "C:\Users\patrik\Documents\ITnetwork\Tvorba\RealtimeKnihaNavstev\Code\PHP">
Pokud máte s nastavením adresáře potíže nebo si ho přejete nastavit pro každý projekt zvlášť, pomůže vám článek Konfigurace PHP (XAMPP).
PHP/index.php
K nastavení Apache je to vše. Nyní vytvoříme soubor
index.php v našem adresáři PHP a otevřeme si tento soubor v
IDE. Jako první nastartujeme sessiony a ob(output buffering - co echujeme se
nebude hned vypisovat, ale ukládat do mezipaměti). Nastavíme kódování na
"UTF-8", dále nastavíme timezone na "Europe/Prague" a načteme si třídu
autoloader, která se nám později bude starat o načítání dalších tříd
(její kód si hned uvedeme). Zaregistrujeme autoloader, vytvoříme
třídu MainClass
a potom zavoláme metodu
mainMethod()
.
session_start(); ob_start(); mb_internal_encoding("UTF-8"); date_default_timezone_set('Europe/Prague'); require('classes/AutoLoader.php'); spl_autoload_register('AutoLoader::load'); $MainClass = new MainClass(); $MainClass->mainMethod();
Nyní si vytvoříme adresář classes
a něm
vytvoříme soubor AutoLoader.php
, v něm vytvoříme
třídu a to AutoLoader
.
PHP/classes/AutoLoader.php
Autoloader
patří k základním kamenům objektové aplikace.
Pokud neprogramujete objektově, tak kromě toho, že byste si znalosti měli
velmi rychle doplnit v seriálu Objektově orientované
programování v PHP, stačí vám zatím informace, že se tato metoda
zavolá vždy, když se snažíme použít nějakou třídu (tu chápejte jako
soubor funkcí). Funkce má za úkol tento soubor načíst podle názvu třídy.
Většinou jen do cesty přidá nějakou složku a za název třídy přidá
koncovku .php
, u nás tomu nebude jinak.
Třída AutoLoader
bude mít veřejnou statickou metodu
load()
, která bude mít parametr
$class
. Jak asi tušíte, metoda load()
bude
obsahovat include()
v podmínce. Když se z nějakého důvodu
nenačte daná třída, vyvoláme výjimku s tím, že danou třídu se
nepovedlo načíst.
Celý soubor bude vypadat nějak takto:
<?php class AutoLoader { public static function load($class) { if(!include("/classes/$class.php")) { header('Content-Type: text/html; charset=utf-8'); throw new ErrorException("Chyba při načítání třídy $class"); } } }
PHP/classes/MainClass.php
Nyní si vytvoříme soubor MainClass.php
a v něm si
třídu MainClass
. Tato třída bude mít dvě metody. Jednu
veřejnou - mainMethod()
a další protected render()
.
MainMethod()
je hlavní metoda, která se při požadavku na
index.php
zavolá. Bude obsahovat pouze volání a výpis
návratové hodnoty metody render
(). Metoda render()
bude obsahovat include šablonového souboru
template.phtml
(který si vytvoříme v příštím
dílu). Celý soubor bude vypadat takto:
<?php class MainClass { public function mainMethod() { echo $this->render(); } protected function render() { return include("template.phtml"); } }
Příště, v lekci Návštěvní kniha přes WebSocket - Zprovoznění komunikace, zprovozníme komunikaci: Klient -> PHP server -> Node.js server ->Klienti.