Download presentation
Presentation is loading. Please wait.
1
PHP Web Applications Architecture and Design
Martin Kruliš by Martin Kruliš (v2.0)
2
Web Application Architectures
Traditional Web Applications /var/www/myweb/ HTTP request Web Server ` index.php Internet mod_php Client Database HTTP response with contents generated by a PHP script by Martin Kruliš (v2.0)
3
Web Application Architectures
Single Page Applications (SPA) Web Server Internet Client Browser downloads static content (HTML, JS, …) HTML document and scripts AJAX, WebSockets, … ajax.php by Martin Kruliš (v2.0)
4
Web Application Architectures
Other Shades of Grey Traditional Applications with AJAX Isolated operations are handled directly in the browser Form validation and autocomplete Paginated view for long repetitive content (tables) Simple single-click operations (e.g., deleting a record) Multiple Connected SPAs Integrating multiple SPA into one larger application which share the user session Typically used when a larger project is created as a composition of independent smaller projects by Martin Kruliš (v2.0)
5
Traditional Web Applications
Expressing UI in the Browser Browser was originally designed as a viewer for static contents (HTML pages) Hyperlinks as controls Leading to the same page with different query params Changing application state of requires HTTP request Only the view state can be changed (HTTP GET request) Forms Smarter forms of hyperlinks (e.g., filter form) Can use POST request to insert/update/delete data at server side Single-button forms (like hyperlinks for POST actions) Actually, expressing the traditional UI in the browser is more complex. For instance, the user may open multiple windows/tabs with the same web application. Furthermore, there might be some controls misconceptions like the back/forward button are not actually performing the role of undo/redo, or stop button may not stop the pending action (merely the page loading). by Martin Kruliš (v2.0)
6
HTTP Wrapper (Revision)
Request Automatically parsed into superglobal arrays $_GET – parameters from request URL $_POST – parameters posted in HTTP body (form data) $_FILES – records about uploaded files $_SERVER – server settings and request headers $_ENV – environment variables Response Script output is included in body of the response Headers may be modified by a function header('header-line'); by Martin Kruliš (v2.0)
7
Data Verification (Revision)
What to Verify or Sanitize Everything that possibly comes from users: $_GET, $_POST, $_COOKIE, … Data that comes from external sources (database, text files, …) When to Verify or Sanitize On input – verify correctness Before you start using data in $_GET, $_POST, … On output – sanitize to prevent injections When data are inserted into HTML, SQL queries, … by Martin Kruliš (v2.0)
8
Input Verification (Revision)
How to Verify (Manually) Regular expressions Filter functions filter_input(), filter_var(), … $foo = filter_input(INPUT_GET, 'foo', FILTER_VALIDATE_INT, $options); Invalid Inputs Ostrich algorithm Attempt to fix (e.g., select a valid part) User errors vs bugs/hack attempts Safely retrieves $_GET['foo'] Additional options based on input type (default, range…) Actually, many DBMS APIs provide a way to prepare SQL statements with properties/variables and then bind values to these properties. Automatic sanitization is then provided. by Martin Kruliš (v2.0)
9
Input Verification Case Study
A form where user edits given name and surname Data from the form are directly used in SQL update What should we test/verify/sanitize? Consider the following inputs: 'Martin', ' Kruliš' 'Da Huc', 'Nguyen' 'Luke ✋', 'Skywalker ☁️' 'Robert\'); DROP TABLE users; --' 'Lorem', 'Ipsum…' (generated megabytes of text) 习近平 Maybe a trim() would be a good idea. No all spaces are wrong (e.g., in the middle of given names) Beware emoji and people who are trying to insert atypical characters. Do not forget to sanitize the data before using them in SQL. Maxlength should be specified on all text inputs + text should be cropped to max length once received. When used directly, you may end up logging SQL error (saving MBs of unnecessary text). And of course, there are many other character sets beside the latin-based ones. by Martin Kruliš (v2.0)
10
Output Sanitization (Revision)
Making sure the output matches target context Automated solutions are preferred How to Sanitize String and filter functions, regular expressions htmlspecialchars() – encoding for HTML urlencode() – encoding for URL DBMS-specific functions (mysqli_escape_string()) Better yet, use prepared statements Actually, many DBMS APIs provide a way to prepare SQL statements with properties/variables and then bind values to these properties. Automatic sanitization is then provided. by Martin Kruliš (v2.0)
11
Web Application Design
Front Controller (Revision) Software design pattern that provides centralized entry point for all request (commands) All URLs point to the same script Actual action is determined from URL query parameters Class (object) Initializing the libraries, setting up components Action … Controller/Presenter … Front Controller (index.php) HTTP Routing and dispatching Method by Martin Kruliš (v2.0)
12
Web Application Design
Front Controller Responsibilities Initialize libraries (typically by autoloading) Load configuration Initialize application (component manager) and essential components (model, logging, …) Get router component and perform routing Get instance of target presenter/controller Verify/sanitize input data Invoke target action on the presenter/controller (providing input data) Collect presenter outputs and complete the request by Martin Kruliš (v2.0)
13
Web Application Design
Routing Get information from URL about what action should be performed And fetch action parameters Router is typically also responsible for creating URLs Example: /?presenter=gallery&action=show&id=42 Presenter class: GalleryPresenter Action method: actionShow() Invocation parameters: id == 42 Router may employ some SEO /gallery/show/42 SEO optimization is based on the common belief that path of the URL is more important to search engines than the query part. With some help from mod_rewrite or something similar by Martin Kruliš (v2.0)
14
Web Application Design
Dispatching class GalleryPresenter extends BasePresenter { public function actionShow($id) { ... } } // $router is already initialized $presenterName = $router->getPresenter(); $presenter = new $presenterName(); // presenter should also be initialized... $actionName = $router->getActionName(); $parameters = $router->getParameters(); $presenter->$actionName(...$parameters); Annotations may be used here Parameter name to position mapping can be determined using reflection Actual dispatching by Martin Kruliš (v2.0)
15
Web Application Design
Model-View-Controller Design pattern that clearly divides responsibilities Handles business logic. Action of the controller is invoked by dispatcher Controller Encapsulates data loading and data manipulation (e.g., in a database) Prepares Manipulates View Loads data from Model Responsible for formatting (presenting) data in HTML (JSON, XML, …) by Martin Kruliš (v2.0)
16
Web Application Design
Model-View-Presenter A derivation of MVC pattern Presenter have similar role as controller Presenter strictly separates model and view View should no longer access model directly Data from model are passed to view by presenter Send events Updates View Presenter Model Prepares Send data by Martin Kruliš (v2.0)
17
Controller/Presenter
One class that represents one (logical) page Wraps interface for the actions Fetching parameters, formatting output Multiple actions Each action is a method Rendering actions Initialize a template, produce HTML (JSON, XML, …) Other actions (POST actions) Update model and respond with redirect Careful when using POST actions for AJAX calls by Martin Kruliš (v2.0)
18
Controller/Presenter
Example class UserPresenter externds Presenter { function actionShow($id) { $user = $this->model->getUser($id); $this->view->render(['user' => $user]); } function actionEdit($id) { $name = $this->getPost('name'); $this->model->setUserName($id, $name); $this->redirect('user', 'show', ['id' => $id]); function signalResetPassword($id) { $this->model->resetUserPassword($id); $this->JSONResponse(['OK' => true]); Renders HTML template Retrieve parameter POSTed from a form Note that this is very crude example (lots of details missing); however, the general of Presenter design is there. 302 response (uses router to generate URL) JSON response to AJAX call by Martin Kruliš (v2.0)
19
Request/Response Encapsulation
PSR-7 HTTP Message Interface Defines two interfaces Psr\Http\Message\RequestInterface Psr\Http\Message\ResponseInterface derived from Psr\Http\Message\MessageInterface These interfaces encapsulate both headers and body of request/response Provide easy access/manipulation with headers Streaming interface for body Better upload handling (UploadedFileInterface) Typically used in more REST oriented frameworks See for more details. A good example of implementation is PHP slim framework. by Martin Kruliš (v2.0)
20
Input Validation (Again)
Dispatcher automatically returns 400 Bad request on failure Employing Annotations /** name (type=string,maxlen=64,required) */ function actionEdit(int $id) { $name = $this->getPost('name'); ... } Extending Request Object function actionEdit(RequestInterface $request) { $request->validatePost([ 'name' => '!string(64)' ]); int is also validator annotation Actual syntax was not taken from any particular network, but the examples have been inspired by Nette (first one) and Laravel (second one) frameworks. There are many other approaches, how to deal with input validation. They share a few common things: Declarative nature. User friendliness (programmer should use them naturally, otherwise they will never be used). Throws exception on error by Martin Kruliš (v2.0)
21
Views Templates Libraries that help with formatting the data (HTML)
Simplifying syntax (abstracting from low level PHP) Providing additional functions for formatting Date, time, currency, … Handling data sanitization (preventing script injection) Handling language translations The controller/presenter prepares the data for the view and the view fills them into the template Many approaches to templating exist Simple frameworks rely on PHP-HTML interleaving, complex ones use their own syntax and preprocessing by Martin Kruliš (v2.0)
22
Views Simple Example Template class View { private $template;
private $parameters; function __get($name) { // sanitize and return // value from $parameters } function render() { require($this->template); Template <html> <head>…</head> <body> <h1><?= $this->title ?></h1> <ul> <?php foreach ($this->list as $item) { ?> <li><?= $item ?></li> <?php } ?> </ul> </body> </html> This is mainly a container for parameters Already sanitized Nested sanitization can be achieved using wrapper objects for instance. Nested sanitization is a bit tricky, but possible Template file is simply included as PHP script by Martin Kruliš (v2.0)
23
Views Latte Templates Example
<h1 n:block=title>Latte Example</h1> <ul n:if="$items"> <li n:foreach="$items as $item">{$item|capitalize}</li> </ul> {if ($user)} <h2>User {$user->login}</h2> Name: {$user->name} Home page: <a n:href="$user->homepage">{$user->homepage}</a> {/if} The same text will appear in the title of the page If and foreach are translated in PHP structures Value filtering Alternative syntax for if statement Context-aware escaping by Martin Kruliš (v2.0)
24
Components Component-based Development
Modern applications use components to promote encapsulation and separation of concerns Component – a software module that provides some well defined functionality through a set of interfaces In PHP, typically represented by a façade singleton that implements well-defined interface(s) Component construction and management A centralized manager (application server, container, …) has to be present to create components Especially to handle component dependencies by Martin Kruliš (v2.0)
25
Make your decomposition SOLID
Components Example Components and their dependencies Presenters Page Logger Mailer Template Renderer User Auth. Database (Model) Make your decomposition SOLID by Martin Kruliš (v2.0)
26
Components Example interface ILog { class SomePresenter {
public actionDo() { ... Log::log("msg"); global $log; $log->log("msg"); $log = Reg::log(); } interface ILog { function log($msg); } class Log implements ILog function log($msg) // open file // append message by Martin Kruliš (v2.0)
27
Dependency Injection Dependency Injection
Design pattern that implements inversion of control Component is not responsible for seeking its own dependencies Dependencies are injected externally (by the container) Declaring dependencies In configuration, by annotations, using reflection, … Problem of cyclic dependencies DB component requires log to log errors Log may require DB component to save messages Tedious to maintain Performance drain by Martin Kruliš (v2.0)
28
Dependency Injection Example /** * @component WelcomePage */
class WelcomePageController implements IController { IDatabase */ public $db; name="NewsService" */ public $news; function __construct(ILog $log) { ... } } Component naming convention Annotations (inject by interface) Annotations (inject by name) Note that injectable properties are public. Both injectable properties and constructor parameters are legitimate ways how to implement DI in PHP. The properties are slightly less error prone as they violate OOP encapsulation; however, unlike constructor parameters, the properties can be used even in cases were cyclic dependencies are detected. FYI: This is just an example, how the injection can work. But it was influenced by Nette framework. Constructor injection (by type hinting) by Martin Kruliš (v2.0)
29
Discussion by Martin Kruliš (v2.0)
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.