Archive for the 'PHP' Category

PHP Session Tutorial

Part 1 - Starting a Session

A session is a way to store information (in the form of variables) to be used across multiple pages. Unlike a cookie, specific variable information is not stored on the users computer. It is also unlike other variables in the sense that we are not passing them individually to each new page, but instead retrieving them from the session we open at beginning of each page.

Call this code mypage.php

    // this starts the session
    session_start();

    // this sets variables in the session
    $_SESSION['color']='red';
    $_SESSION['size']='small';
    $_SESSION['shape']='round';
    print "Done";

The first thing we do with this code, is open the session using session_start(). We then set our first session variables (color, size and shape) to be red, small and round respectively.

Just like with our cookies, the

session_start()

code must be in the header and you can not send anything to the browser before it. It’s best to just put it directly after the to avoid potential problems.

So how will it know it’s me? Most sessions set a cookie on your computer to uses as a key… it will look something like this: 350401be75bbb0fafd3d912a1a1d5e54. Then when a session is opened on another page, it scans your computer for a key. If there is a match, it accesses that session, if not it starts a new session for you.

Part 2 - Using Session Variables

Now we are going to make a second page. We again will start with session_start() (we need this on every page) - and we will access the session information we set on our first page. Notice we aren’t passing any variables, they are all stored in the session.

Call this code mypage2.php

    // this starts the session
    session_start();

    // echo variable from the session, we set this on our other page
    echo "Our color value is ".$_SESSION['color'];
    echo "Our size value is ".$_SESSION['size'];
    echo "Our shape value is ".$_SESSION['shape'];

All of the values are stored in the $_SESSION array, which we access here. Another way to show this is to simply run this code:

    session_start();
    Print_r ($_SESSION);

You can also store an array within the session array. Let’s go back to our mypage.php file and edit it slightly to do this:

    session_start();

    // makes an array
    $colors=array('red', 'yellow', 'blue');
    // adds it to our session
    $_SESSION['color']=$colors;
    $_SESSION['size']='small';
    $_SESSION['shape']='round';
    print "Done";

Now let’s run this on mypage2.php to show our new information:

    session_start();
    Print_r ($_SESSION);
    echo "

";

    //echo a single entry from the array
    echo $_SESSION['color'][2];

Part 3 - Modify or Remove Session

    // you have to open the session to be able to modify or remove it
    session_start();

    // to change a variable, just overwrite it
    $_SESSION['size']='large';

    //you can remove a single variable in the session
    unset($_SESSION['shape']);

    // or this would remove all the variables in the session, but not the session itself
    session_unset();

    // this would destroy the session variables
    session_destroy();

The code above demonstrates how to edit or remove individual session variables, or the entire session. To change a session variable we just reset it to something else. We can use unset() to remove a single variable, or session_unset() to remove all variables for a session. We can also use session_destroy() to destroy the session completely.

By default a session lasts until the user closes their browser. This can be changed in the php.ini file by change the 0 in session.cookie_lifetime = 0 to be the number of seconds you want the session to last, or by using session_set_cookie_params().

About.com

Member Area PHP Script

// Connects to your Database
mysql_connect("your.hostaddress.com", "username", "password") or die(mysql_error());
mysql_select_db("Database_Name") or die(mysql_error());

//checks cookies to make sure they are logged in
if(isset($_COOKIE['ID_my_site']))
{
$username = $_COOKIE['ID_my_site'];
$pass = $_COOKIE['Key_my_site'];
$check = mysql_query("SELECT * FROM users WHERE username = '$username'")or die(mysql_error());
while($info = mysql_fetch_array( $check ))
{

//if the cookie has the wrong password, they are taken to the login page
if ($pass != $info['password'])
{ header("Location: login.php");
}

//otherwise they are shown the admin area
else
{
echo "Admin Area

";
echo "Your Content

";
echo "Logout";
}
}
}
else

//if the cookie does not exist, they are taken to the login screen
{
header("Location: login.php");
}

This code checks the cookies to make sure the user is logged in, the same way the login page did. If they are logged in, they are shown the members area. If they are not logged in they are redirected to the login page.

PHP Inheritance

interface hasArea {
	public function getArea();
}

class Rectangle implements hasArea {
	static $w;
	static $l;
	public function __construct($w, $l) {
		$this->w = $w;
		$this->l = $l;
	}

	public function getArea() {
		return $this->w * $this->l;
	}
}

class Square extends Rectangle {
	public function setWidth($w) {
		parent::$w = $w;
	}

	public function setLength($l) {
		parent::$l = $l;
	}

	public function getArea() {
		return parent::$w * parent::$l;
	}

	public function getArea2() {
		return $this->w * $this->l;
	}
}

$rect = new Rectangle(10, 5);
print $rect->getArea();
print "";
$sqr = new Square(5, 5);
print $sqr->getArea();
print "";
print $sqr->getArea2();
print "";
$sqr->setWidth(10);
$sqr->setLength(10);
print $sqr->getArea();

/*
	Output:
	50
	0
	25
	100
*/

PHP supports inheritance and polymorphism. The above is one tiny example when I played around with it. If you see the output, you realize that setWidth and setLength would set the parent variable, in which is NOT set even I’ve instantiated Rectangle using $w and $l parameter on its constructor.

PHP Paging

config.php

$username = 'username';
$password = 'password';
$database = 'dbname';
$table = 'dbtable';
$host = 'localhost';

$rowsPerPage = 10;
$pageNum = 1;

opendb.php

include('config.php');
$link = mysql_connect($host, $username, $password);
if (!$link) {
	die('Could not connect: ' . mysql_error());
}
mysql_select_db($database);

closedb.php

include('config.php');
mysql_close($link);

index.php

include('opendb.php');

// if $_GET['page'] defined, use it as page number
if(isset($_GET['page'])) {
    $pageNum = $_GET['page'];
}

// counting the offset
$offset = ($pageNum - 1) * $rowsPerPage ;

// selecting $rowPerPage, starting from $offset
$query = "SELECT * FROM " . $table . " LIMIT " . $offset . " , " . $rowsPerPage;
$result = mysql_query($query) or die ('Error, query failed');
$totalRows = mysql_num_rows($result);

while($row = mysql_fetch_array($result)) {
   echo $row['fname'] . '';
}

// how many rows we have in database
$query   = "SELECT COUNT(*) AS numRows FROM " . $table;
$result  = mysql_query($query) or die('Error, query failed');
$row     = mysql_fetch_array($result, MYSQL_ASSOC);
$numRows = $row['numRows'];

// how many pages we have when using paging?
$maxPage = ceil($numRows/$rowsPerPage);

// print the link to access each page
$self = $_SERVER['PHP_SELF'];
$nav  = '';

for($page = 1; $page <= $maxPage; $page++) {
   if ($page == $pageNum) {
      $nav .= " " . $page . " "; // no need to create a link to current page
   } else {
      $nav .= " " . $page . " ";
   }
}

// creating previous and next link
// plus the link to go straight to
// the first and last page

if ($pageNum > 1) {
   $page  = $pageNum - 1;
   $prev  = " [Prev] ";

   $first = " [First Page] ";
} else {
   $prev  = ''; // we're on page one, don't print previous link
   $first = ''; // nor the first page link
}

if ($pageNum < $maxPage) {
   $page = $pageNum + 1;
   $next = " [Next] ";

   $last = " [Last Page] ";
} else {
   $next = ''; // we're on the last page, don't print next link
   $last = ''; // nor the last page link
}

// print the navigation link
echo $first . $prev . $nav . $next . $last;

include('closedb.php');

I think the code is pretty straight forward other than understanding on how does the $offset works. Also, I just knew that in PHP you could do something like:

$var = 1;
print("some $var");

That means you could combine both variable and string. PHP takes care to differentiate between the real string and variable. So, you don’t have to do all of the complicated stuff by adding dots as you see in my code. However, I always like to make it explicit.. :).. As you see in this code that I’m still using dots all around, well, it does get more complicated when you’re dealing with more variables, but that way my IDE would be able to differentiate between the real variable and string. That means it adds my visibility when looking at the codes.

Download the code

How to Secure a Folder using Basic HTTP Authentication?

You should read on if you are not going to secure data that is very sensitive such as Social Security Number. I’m not security expert, and I’m not responsible for any loss or damages.

You have control over a web server, and you want to secure a folder within the web server using basic HTTP authentication. What is that? If you’ve seen a pop up dialog box when you’re about to enter a web page on a site like:

OR

They’re both a basic HTTP authentication.

There are many ways to implement the basic HTTP authentication. In PHP for example, you could easily implement this in few lines of codes:

if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Text to send if user hits Cancel button';
    exit;
} else {
    echo "

Hello {$_SERVER['PHP_AUTH_USER']}.

";
    echo "

You entered {$_SERVER['PHP_AUTH_PW']} as your password.

";
}

However, note that in PHP, the authentication process applies to those who’s trying to access the PHP page that contains the above code. But what if you want to secure the whole folder that contains many files, and list them when the user is authenticated, otherwise, then they can’t see and/or download the files within the folder.

Note that the web server that I’m using in this tutorial is Apache. I’m using XAMPP, but it doesn’t matter whether you’re using XAMPP or not, because we still need to use the htpasswd that comes with the Apache. In XAMPP, you’ll find this in xampp/apache/bin

Once you create a folder in the web server, then make sure that you know the full path from the root  to the folder that you want to secure, and then create .htaccess file that contains the following lines:

AuthUserFile “/www/www/full/path/to/your/folder/.htpasswd”
AuthName “Message to go on user’s login screen”
AuthType Basic
Allow from all
Require valid-user
Options +Indexes

After that, you have to create .htpasswd file, which would be created by the htpasswd that is located in the bin folder of the Apache.

Usage:
htpasswd [-cmdpsD] passwordfile username
htpasswd -b[cmdpsD] passwordfile username password

htpasswd -n[mdps] username
htpasswd -nb[mdps] username password
-c  Create a new file.
-n  Don’t update file; display results on stdout.
-m  Force MD5 encryption of the password (default).
-d  Force CRYPT encryption of the password.
-p  Do not encrypt the password (plaintext).
-s  Force SHA encryption of the password.
-b  Use the password from the command line rather than prompting for it.
-D  Delete the specified user.
On Windows, NetWare and TPF systems the ‘-m’ flag is used by default.
On all other systems, the ‘-p’ flag will probably not work.

Now, type htpasswd -c username username, Apache will then ask you for a password to be encrypted. If you don’t use SHA encryption, the default encryption would be the MD5. There will be username file that is created in the bin directory, and when you open it, you’ll see something like:

username:$apr1$L1f68a53$8Hq14C3aFwqZCAosvxtW60

Now just rename the file to be .htpasswd, then put in the folder where .htaccess is:

/www/www/full/path/to/your/folder/.htpasswd
/www/www/full/path/to/your/folder/.htaccess

Done, then just open up browser, and go to http://localhost/folder or try download a file within the folder http://localhost/folder/file.pdf.

Note that each line of the .htpasswd file represents one username and password, and you could always add multiple user accesses by appending additional username followed by the colon “:” and then the encrypted password to the .htpasswd.

Zend Framework Quickstart

If you’re lazy of copying and pasting from the official Zend Quickstart Tutorial, then just download it here. Extract it, and you’re set to go with Zend Framework!

Simple PHP MySQL Injection Prevention

An example SQL Injection Attack

// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='{$_POST['username']}'
     AND password='{$_POST['password']}'";
mysql_query($query); // We didn't check $_POST['password'],
                     // it could be anything the user wanted! For example:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
// This means the query sent to MySQL would be:
echo $query;
?>

The query sent to MySQL:

SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

This would allow anyone to log in without a valid password.

Using mysql_real_escape_string() around each variable prevents SQL Injection. This example demonstrates the “best practice” method for querying a database, independent of the Magic Quotes setting.

if (isset($_POST['product_name']) && isset($_POST['product_description'])
      && isset($_POST['user_id'])) {// Connect
    $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
    if(!is_resource($link)) {
          echo "Failed to connect to the servern";
          // ... log the error properly
    } else {
    // Reverse magic_quotes_gpc/magic_quotes_sybase effects on those vars if ON.
    if(get_magic_quotes_gpc()) {
    $product_name        = stripslashes($_POST['product_name']);
    $product_description = stripslashes($_POST['product_description']);
} else {
    $product_name        = $_POST['product_name'];
    $product_description = $_POST['product_description'];
}
// Make a safe query
$query = sprintf("INSERT INTO products (`name`, `description`, `user_id`)
        VALUES ('%s', '%s', %d)",
mysql_real_escape_string($product_name, $link),
mysql_real_escape_string($product_description, $link),
$_POST['user_id']);
mysql_query($query, $link);
if (mysql_affected_rows($link) > 0) {
     echo "Product inserted";
} else {
echo "Fill the form properly";
}
?>

The query will now execute correctly, and SQL Injection attacks will not work.