NSWI142: Web Applications

PHP and MySQL

Preliminaries

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 prepare in advance. Following these instructions will help you get the most out of the seminar and ensure smooth participation.

Preliminaries

Before the start of the practical, you should be able to:

  • Explain Model-View-Presenter and how to use it with PHP.
  • Explain what is SQL and what is a relation database.
  • Use SQL commands CREATE, UPDATE, SELECT, and DELETE.
  • Explain what are prepared statements and how we can use them.

Preliminaries software

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:

  • You have enabled mysqli extension in your php.ini file.
    You can test this by executing following code snippet.
    
              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.

Demonstration: Semestral project

A draft of semestral project assignment is out. You have a week to provide feedback. At the ent of the next week, we are going to publish the final version.

Relational database

MySQL on webik

There is a MySQL server running on webik server. The database is accessible only from webik itself, i.e. localhost. You can interact with the database using various tools:

How to connect?

  • Host: localhost
  • Port: 3306
  • Username: {username}
  • Password: your original password sent to you at the beginning of the course
  • Database: stud_{username}

Accessing webik MySQL remotely

Use SSH tunneling to forward the MySQL port from Webik to your local machine.


      ssh -L 3306:localhost:3306 webik
    

This expose the database port 3306 on your local machine at 3306.

MySQL and PHP

Do NOT use the old mysql_* functions!

Connecting to the Database

Using procedural API:


$connection = mysqli_connect($host, $user, $password, $database);
if (!$connection) { /* handle error */ }

// ... work with connection

mysqli_close($connection);
    

Using object oriented API, this is the preferred way:


$mysqli = new mysqli($host, $user, $password, $database);
if ($mysqli->connect_error) { /* handle error */ }

// ... work with connection

$mysqli->close();
    

If a query fails, error message can be obtained using mysqli_error. See documentation for object oriented and procedural version.

Working with database connection

It is common to utilize a single connection per user request, i.e. per PHP script invocation. Do NOT create a new connection for every SQL query.

SQL connection is closed automatically after script execution. Yet, it is highly recommended, mandatory for NSWI142, to close is once you do not need it.

Executing static SQL


      $query = "SELECT * FROM MyTable";
      if ($result = $mysqli->query($query)) {
        /* fetch associative array */
        while ($row = $result->fetch_assoc()) {
          // access $row["Column1"], $row["Column2"], ...
        }
      }
    

Use only for static query with NO user input.

See mysqli_result class documentation for more details.

Executing (dynamic) SQL

Preferred solution for query execution is to employ 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);

      // We can change it later.
      $aStringVar = '...';
      $aDoubleVar = 0;

      $stmt->execute();
      $query_result = $stmt->get_result();
    

SQL injection

SQL injection

What is SQL injection?

SQL Injection is technique abusing SQL statements constructed from user inputs without proper sanitization. Similar technique can be employed in other scenarios as well.

Is can be leveraged to extract database data, tamper with existing data, spoof identity, escalate privileges, …

Hackers ARE interested in my little website.

Do NOT try this at home !


$query = 'SELECT * FROM products WHERE title = "'. $_GET['search'] . '"';
$query_result = mysqli_query($conn, $query);
      

Preventing SQL Injection

There is section about SQL Injection in PHP manual.

You can try and use sanitization functions. For example, mysqli_real_escape_string performs sanitization for SQL. It works like htmlspecialchars, just for SQL instead of HTML.

It is best to not rely on them and instead use solution like templates or prepared statements. Use of prepared statements instead of mysqli_real_escape_string is mandatory for NSWI142.

Exercise: List items in the database

Just a simple PHP application, connect to a database and list the content.

Exercise: List items in the database

Create a table 'articles' with (id INT(4) NOT NULL PRIMARY KEY AUTO_INCREMENT, name VARCHAR(128), preview VARCHAR(255), published DATE) and populate the table with data.

With the database ready, create a PHP file which

  • Connect to the database.
  • List stored items in the table.

If you are not sure about working with SQL you can utilize login bellow with pre-populated data.

  • server: localhost
  • login: public
  • password:
  • database: public

Continue to the next slide once you are done.

Add filters

Add support for filtering. A user should be able to utilize following filters:

  • published is not null
  • preview like %..%

The filter, user query, must be stored in URL query. Thus the the user can refresh, or share, the page.

Here is a link on how to utilize LIKE with prepares statements.

Continue to the next slide once you are done.

List items in the database?

Continue to the next slide once you are done.

Task Complete

Congratulations, if you have followed the instructions, you have just reached the end of this exercise.

Exercise: Who gets the bonus point?

List of students to receive a bonus point.

Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.