Štěpán Stenchlák, KSI
stepan.stenchlak@matfyz.cuni.cz
Please read this section at least one day prior to the seminar. This section outlines what you are expected to know, be able to do, or have prepared in advance. Following these instructions will help you get the most out of the seminar and ensure smooth participation.
Before the start of the practical, you should be able to:
CREATE, UPDATE, SELECT, and DELETE.This slide applies to you only if you plan to use your own computer for the practical.
Before the start of the practical, make sure that:
new mysqli('localhost', 'my_user', 'my_password', 'my_db');
If you get
... Uncaught Error: Class "mysqli" not found in php shell code: ...
exception, the extension is likely not properly enabled.
New task PHP - REST API Router (non-mandatory, 2 points).
First draft of semestral project assignment: teaching.mff.cuni.cz/nswi142-web/semestral-project/. Please give us feedback if something is unclear. At the end of the next week, we will publish the final version.
There is a MySQL server running on Webik, but it is accessible only from Webik itself (due to firewall rules).
localhoststud_<username>You can try logging in via Adminer on webik.ms.mff.cuni.cz/adminer.
Feel free to use your own SQL database for development, but you will be required to use Webik's MySQL database for your semestral project.
You can also use:
mysql -p from Webik server.Use SSH tunneling to forward the MySQL port from Webik to your local machine.
ssh -L 3306:localhost:3306 webik
Then, you can use 127.0.0.1 as host for MySQL connection on your PC.
Note: According to the documentation, we cannot use localhost as it is bound to Unix sockets, which we do not have. Therefore, you need to use 127.0.0.1 to explicitly indicate that we want a TCP/IP connection.
Do not forget to have mysql php extension installed. (On Linux, install php-mysql.)
Basic use of Adminer on Webik:
Using the object-oriented API:
$mysqli = new mysqli($host, $user, $password, $database);
if ($mysqli->connect_error) { /* handle error */ }
// work with the connection for the whole duration of the script ...
$mysqli->close();
Connection is closed automatically after the script execution. As a result, closing the connection is in general optional. For you, it is mandatory for NSWI142.
Do NOT use the old mysql_* functions!
Utilize a single connection per user request (i.e., one PHP script invocation). Do NOT create a new connection for every SQL query.
If a query fails, an error message can be obtained using $mysqli->error. See the documentation for the object-oriented and
procedural versions.
Using the object-oriented API:
if ($result = $mysqli->query("SELECT * FROM MyTable")) {
// fetch associative array
while ($row = $result->fetch_assoc()) {
// access $row["Column1"], $row["Column2"], ...
}
}
Use only for static queries with NO user input.
See mysqli_result class documentation for more details.
SQL Injection is technique abusing SQL statements constructed from user inputs without proper sanitization. Similar technique can be employed in other scenarios as well.
It can be leveraged to extract database data, tamper with existing data, spoof identity, escalate privileges, …
Hackers ARE interested in my little website.
Don't Try This at Home !!!
$query = 'SELECT * FROM products WHERE title = "'. $_GET['search'] . '"';
$query_result = $mysqli->query($query);
There is a section about SQL Injection in PHP manual.
There are functions that can escape strings similar to htmlspecialchars for HTML. Using them is not recommended.
Use prepared statements with bound variables.
// Notice no quotes around '?'.
$stmt = $mysqli->prepare("INSERT INTO myTable VALUES (?, ?)");
// Bind variables to '?' with hinting the type (string, double).
// Function takes references, thus you must use variables.
$stmt->bind_param('sd', $aStringVar, $aDoubleVar);
$stmt->execute();
$query_result = $stmt->get_result();
Modify the EventModel from the last practicals to use MySQL database instead.
Hints (go further to reveal them):
event table, user - user table. Then, tables for m:n relations: user is registered to event - event_participant table.id INT(4) NOT NULL PRIMARY KEY AUTO_INCREMENT/events.Hints (go further to reveal them):
<?php
$query = "SELECT * FROM articles";
$bindTypes = "";
$bindValues = [];
if (...) {
$query .= " WHERE name LIKE ?"; // Check SQL LIKE operator if needed
$bindTypes .= "s";
$bindValues[] = "%" . $searchTerm . "%";
}
$mysqli->prepare($query);
if (count($bindValues) > 0) {
$stmt->bind_param($bindTypes, ...$bindValues);
}
Create a template for a 404 page.
Implement an ErrorPresenter that is called when the Front Controller cannot find an appropriate Presenter. Don't forget to return a 404 status code.
List of students to receive a bonus point. Deadline next practicals.