Week 10: Remote resources, sessions and advanced PHP

by Andres Baravalle

Remote resources, sessions and advanced PHP

  • Remote resources, filesystem functions and mail
  • Forms and querystrings
  • Cookies and sessions
  • Testing

Remote resources, filesystem functions and mail

Filesystem functions

PHP includes a large number of filesystem functions.

You will find useful to familiarise yourself with the ones in the next slides. For the full list of functions, please refer to the PHP on-line documentation.

Reading and writing from files

file_get_contents() Reads entire file into a string
file_put_contents() Write a string to a file
file() Reads an entire file into an array
parse_ini_file() Loads in the ini file specified and returns the settings in it in an associative array
readfile() Reads a file and writes it to the output buffer

Using remote resources

file_get_contents(), file() and readfile() can be also be used to get a remote resource.

Getting information on files

file_exists() Checks whether a file or directory exists
dirname() Returns the parent directory's path
basename() Return the trailing name component of a path
realpath() Expands all symbolic links, resolves references to '/./', '/../' and extra '/' characters in the input path and returns the canonicalized absolute pathname.

Activity #1: screenscraping PhDComics

Use a combination of file_get_contents() and regular expressions to include today's t comic strip from phdcomics.com into an HTML page.

Activity #2: screenscraping Dilbert

Use a combination of file_get_contents() and regular expressions to include today's Dilbert comic strip into an HTML page. To facilitate your work, you should disable JavaScript on your browser, as Dilber's web site has anti-screenscraping features.

Activity #3: BBC news

Use a combination of file_get_contents() and regular expressions to extract all the images in http://feeds.bbci.co.uk/news/rss.xml. Show them in your web page.

Forms and querystrings

$_POST & $_GET

PHP can be used to easily process forms submitted by users. $_POST and $_GET variables are automatically populated when submitting a form, and will contain the valutes of the form submitted.

$_POST is an array populated when the form is submitted using the HTTP post method. $_GET is populated when using get. You define the method in your HTML form

HTML forms and PHP

The value of each element of the form will be stored in the $_POST or $_GET variable. You must set up the name attributes in your elements appropriately (e.g. with meaningful names).

PHP and forms: a practical example

In the next few slides we're going to walk through an example of using a form to build a basic authentication backend with PHP.

In the example, the form and the parsing function are in the same page (the code for the example is available here).

In our example, the the usernames and passwords are stored in the same file where the form is. Under normal circumstances they would be stored in configuration files (for a system with few users only) or in a database.

Please note that in our implementation, passwords are not stored directly, but they are salted and hashed (read this for an explanation of why).

PHP and forms: writing the form

<form method="post" action="<?php echo $PHP_SELF; ?>"> 
	<div>
		<label for="name">username</label>
		<input type="text" name="name">
	</div> 
	<div>
		<label for="password">password</label>     
		<input type="text" name="password">
	</div> 
	<div>
		<input type="submit">
	</div>
</form>

PHP and forms: parsing the data


<?php
$username = "john"; 
$salt = "ab13"; 
// password: savage (crypt'ed & salted) 
$password = "abB/9oNNOMLGY"; 

/* sample $_POST
    Array
    (
        [name] => john
        [password] => savage
    )
*/

if(isset($_POST["name"]) and isset($_POST["password"])) {     
	if($_POST["name"] == $username and crypt($_POST["password"], $salt) == $password ) {         
		echo "<p>You are now logged in in the system.</p>";     
	}         
	else {         
		echo "<p>Incorrect username/password combination.</p>";     
	}
}
?>

Activity #4: parsing forms

Create a contact form including name, surname, mobile telephone number and a UEL email address. The form will be processed by that very same PHP page with $_POST:

  • Check the $_POST array to decide whether to display the form or parse its content
  • Use regular expressions to validate the form on the server side and ensure that the users has filled all the elements appropriatelly; if any field contains incorrect/unexpected content, return an error and communicate it to the user.

Sending emails

Email is sent with the mail() function. Your server/workstation needs a configured mail server/mail gateway for the mail function to work.

Activity #5: sending email

Update the form you developped in the previous activity to send a email notification after each log-in, as a security measure.

QUERY_STRING and PATH_INFO

$_SERVER["QUERY_STRING"] is one of the server variables exposed by PHP. It evaluates to the string at the right of the ? sign in a URL.

http://www.example.com/index.php?this_is_my_query_string

$_SERVER['PATH_INFO'] evaluates to the string at the right of the last / sign in a URL.

http://www.example.com/this_is_my_path_info.php

http://www.example.com/index.php/this_is_also_my_path_info

Using QUERY_STRINGs and PATH_INFO

Querystrings and path_info can be used to pass parameters across your PHP pages:

  • http://www.example.com/index.php?page=home
  • http://www.example.com/index.php?page=form&action=process
  • http://www.example.com/index.php/form/process

This approach is heavily used in large applications as Wordpress, Magento and Drupal.

Cookies and sessions

Cookies

Cookies are small pieces of information that scripts can store on a client machines. Cookies are sent through HTTP headers (which means that they must be set before the output of any code in the web page).

Setting cookies

A cookie can be set with the function setcookie(); below a simplified prototype:

bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path]]])

  • name is the name for the cookie; use them to distinguish the information you want to save
  • value is the value of the information
  • expire is the time the cookie expires (as a unix timestamp)

Reading cookies

Cookies are stored in the $_COOKIES array.

Cookies limitations

Know limiting factors in the use of cookies include:

  • Users disabling cookies to avoid being tracked (think AdWords or similar programs)
  • Privacy concerns: cookies could leave sensitive data accessible to attackers with access to a PC
  • RFC 2965, the document that defines how cookies work, specifies that there should not be any maximum size, but in practice browsers typically limit the maximum size of cookies to around 4,000 bytes

Sessions

In practise, cookies are typically used to store a session id; that session id is then matched in web applications to session variables.

The local computer will just store the name of the session, which will be transmitted to the server every time a new page from the server is loaded. The server will match the session id sent with it's list of session and load any data as needed.

How to use sessions?

Sessions are normally used to store data from the user, to improve the experience of users on the web site.

Typical information stored includes:

  • Number of visits to the web site
  • Pages visited on each visit
  • Dates/times for visits in the website

What is important is that sessions allow to monitor users without identifying them. Sessions are heavily used in advertisement (cookies are associated with domains - so advertisers can keep track of what web sites you have been visiting if they are part of their network).

Using sessions in PHP

<?php
// page1.php
session_start();
echo 'Welcome to page #1';
$_SESSION['pages']['timestamp'] = array($_SERVER['PHP_SELF'], time());
?>

Testing

Software testing

"Software testing is an investigation conducted to provide stakeholders with information about the quality of the product or service under test.

Software testing can also provide an objective, independent view of the software [...]. Test techniques include, but are not limited to the process of executing a program or application with the intent of finding software bugs". (Wikipedia, 2013)

Software testing (2)

"Software testing can be stated as the process of validating and verifying that a computer program/application/product:

  • meets the requirements that guided its design and development,
  • works as expected,
  • can be implemented with the same characteristics,
  • and satisfies the needs of stakeholders."

(Wikipedia, 2013)

Static vs Dynamic testing

Static testing is a form of software testing focusing on checking the sanity of the code. This type of testing is often used by the developer who wrote the code, but can be used also in team environments.

Common approaches used for static testing include code reviewsinspections and software walkthroughs. Most modern editors for programmers support some automatic code reviews to some extent.

Dynamic testing refers to the examination of the response from the system when a software runs. It involves working with the software, giving input values and checking if the output is as expected by executing specific test cases.

Testing levels

The main levels of testing during the development process are:

  • Unit testing
  • Integration testing
  • System testing
  • Acceptance testing

Unit testing

Unit testing refers to tests that verify the functionality of a specific section of code, usually at the function level (procedural programming) or at class level (OO programming).

These types of tests are usually written by developers as they work on code, to ensure that the specific function is working as expected.

In PHP, unit testing is typically done using PHPUnit.

Integration testing

Integration testing is used to verify the interfaces between components. Integration tests aim to test a web application as a whole and is specifically important when different developers are working at different parts of the system.

"Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly." (Fowler, 2006) 

There is no de-facto standard for integration testing in PHP applications; tools that can be used to do integration testing of PHP applications include CruiseControl and Hudson.

Sysems testing

System testing tests a completely integrated system to verify that it meets its requirements.  A PHP as well as working as expected in an environment that reflects the real-use conditions.

Example of system testing tecniques used to test web applications include:

  • Graphical user interface testing
  • Usability testing
  • Software performance testing
  • Load testing and stress testing
  • Security testing
  • Installation testing

Acceptance testing

Acceptance testing is the final  test conducted to determine if the requirements of a specification are met. Acceptance testing can be performed by a non-technical person, which can be a manager or a client.

Testing your web applications

At this stage, we are not going to cover unit, integration or system testing any further - but we are going to focus on acceptance testing using CodeCeption.

Using CodeCeption

CodeCeption

In the next slides we are looking at how to use CodeCeption to test our PHP applications.

CodeCeption can be used to run a wide range of tests, but we are going to focus on acceptance testing.

To use CodeCeption you need command line access. You cannot run the tests simply from a browser interface, but you will need a shell to bootstrap your test environment and create your skeleton files.

To install and bootstrap CodeCeption, please complete the next activity. You will also need an application to test; if you do not have an application, you can test the form file that we have written earlier on.

CodeCeptions: testing a home page


<?php  
$I = new WebGuy($scenario);
$I->wantTo('ensure that frontpage works');
$I->amOnPage('/');
$I->see('Home');
?>

CodeCeptions: testing a form

<?php
$I = new WebGuy($scenario);
$I->wantTo('log in');
$I->amOnPage('/week_10_form.php');
$I->fillField('username','john');
$I->fillField('password','savage');
$I->click('Submit');
$I->expect('to be logged in');
$I->see('You are now logged in in the system');
?>

Activity #5: installing and bootstrapping CodeCeption

Follow the tutorial here and write some basic tests for your project:

  • Check that it can create new users
  • Check that users can log-in and that users cannot log-in with the wrong password
  • Check that a list of quizzes appears on the home page