Welcome

To my corner on the net... Warning, this is a techie blog! Non-techie people may suffer bouts of epilepsy on viewing this blog. The author cannot be held responsible.

PHP and MySQL

Tuesday, 26 April 2011

This is PHP with MySQL week ! I had already done some work previously with MySQL but usually using the VB.net platform. I usually prefer to use MS SQL over MySQL but this is basically because I am more familiar with the former. My experience with MySQL comes more from tweaking web sites that use this popular database system in their CMS back-ends.

I also did some reading about the history of the MySQL relational database system simply out of interest where this free system came from. I was not aware, for example, that MySQL is now owned by Oracle and that it sells for USD 2000. Thankfully MySQL has a "Community Version" which is licensed under the GPL. I must admit I had to do some searching to be able to understand the difference between the Community Version and the Standard Version. The Enterprise Version which is even more expensive does seem to have advanced features such as "partitioning" and an integrated backup system, however the difference between the Standard and Community editions was not immediately clear. It seems that basically both version have the same functionality and defer only in the availability of (Oracle) support and the licensing policy. The Community edition is published under the GPL so if the application being developed is not published under the GPL license it is not legal to bundle MySQL with the application and the user would have to purchase the Standard Edition at least. When compared with the limitations that MSSQL Express has over the commercial edition of the same database, the MySQL  version are much more close. This in turn has had to be one of the main reasons why MySQL is so popular for web based applications.


The MySQL Command Line
Although I had used MySQL in the past, it was usually remotely through shared hosting on third party servers so I rarely had the opportunity to use the command line. On shared hosting systems, Telnet is usually not allowed so there is not much chance of using the command line. I had done some work with MySQL with Delphi using ODBC connectors as well as with VB.NET.

Next screen shows logging into the local MySQL server using the command line interface. The server reports that the version is the "Community" version.



Next screen shows use of the "status" command which displays the current status of the server. It also shows the character set encoding. I have had some bad experiences with the encoding of MySQL databases in my work designing and implementing websites using Joomla. I have had to produce languages in various languages including Maltese, Arabic and even some Japanese. Joomla, by default installs with an encoding that is not capable of displaying the special characters in these languages. To my detriment I discovered that there is no way, through phpMyAdmin to change the encoding globally. This meant that I had to change the encoding for every table separately which meant a lot of extra work. Usually I install Joomla through the automated "Fantastico" panel which installs it automatically and for some reason it chooses a character set that does not display the special characters in these languages correctly.


Next screen shows the help content and the root user connecting. It also shows that when first connected, there are no databases selected. 


Next screen shows the "show databases" command which lists the databases that are available. It shows the "test" database that was created in another series of experiments prior to my writing of this blog.


This  next screen shows selecting a database, in this case selecting the "test" database and then using the "show tables" command which lists the existing tables, namely the "users" database.


The next screen shows creating a new table called "userstable" and then listing the tables available which includes this new table proving that it was created successfully.


This next screen shot shows phpMyAdmin loaded through my Firefox browser showing the two tables that exist under the "test" database. I could of course have used phpMyAdmin to create  the tables but as I had done this many times before but never through the CLI I decided to use the CLI above to create the new table.


Usually when I do any work with MySQL I use a third party application called "Navicat for MySQL" which has the look and feel of the "SQL Developement Studio" that comes bundled with Microsoft SQL Server which I am much more accustomed to. The next screen show shows Navicat in action.



Checking login against a MySQL Database

I have modified the code so that instead of comparing the login and password with values stored in an array, we now compare them with records in a database.

The code below is from the page that generates the form. I have originally made all the markup to draw the form  in an "echo" block but after reading I realised that this is not the preferred method although it works just as well. It is better to open and close the "php tag" rather then echo markup to keep the script more understandable.




loginFormDbase.php

<html>
    <head>
        <title>Php Form</title>
        </head>
        <body>
    <?php
    session_start();
    if(isset($_SESSION['user'])) {echo "Welcome " . $_SESSION['user'] . "!<br />";
    echo "<form name='login_form' method='post' action='logoutdbase.php'>
            <input type='submit' name='Logout' value='logout'>";
    }
            else {?>

<form name='login_form' method='post' action='checklogindbase.php'>
<table border='1' width='30%'><tr><td>
<table  width='100%' cellpadding='10' cellspacing='1'>
<tr><td colspan='2'><center>Login Form</center></td></tr>
<tr><td>Login Name</td><td><input name='user' type='text' id='user'></td></tr>
<tr><td>Password</td><td><input name='pass' type='password' id='pass'></td></tr>
<tr><td>Remember me</td><td>
<input type='checkbox' name='rememberme' id='rememberme' value='yes'></td></tr>
<tr><td colspan='2'><input type='submit' name='Submit' value='Login'></td></tr>
</table>
</td></tr></table>
<?php
    }
                      ?>
    </body>
</html>


The next script checks the login and password against the database. I have enclosed the processes in this script with the MySQL connection "If" block to ensure that the script does not attempt to continue if a connection to the underlying database cannot be made for some reason. The  if (is_resource($result)) block which also surrounds the processes on this page is another safety measure and is there to make sure that the script is terminated if a result set is not returned from the MySQL transaction.

During lectures we also attempted to hack our own scripts using SQL injection techniques. This was not too difficult to achieve as we had not yet included any measure to prevent these attacks. The @mysql_real_escape_string replaces suspicious characters and should be effective to prevent SQL injection attacks.



checklogindbase.php

<?php
        //get variables from the form
        $user=$_POST['user'];
        $pass=$_POST['pass'];
   
           
    //remove to protect against sql injection
    $user = mysql_real_escape_string($user);
    $pass = mysql_real_escape_string($pass);
   
    //Open connection to the local MySQL Server
    $con = mysql_connect("localhost","root","root");
    if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
    //will only continue if a good connection is made
    else {
    mysql_select_db("test", $con);
    $result = mysql_query("SELECT * FROM usersTable");
   
    //Will only continue if the result has been retreived from the database
    if (is_resource($result))
    {
    $loginOk = false;
    while($row = mysql_fetch_array($result))
    {
        if (($row['username'] == $user) and ($row['password'] == $pass)) {
        $loginOk = true;

        //Remember me was checked so we set the session
            if(isset($_POST['rememberme'])) {$rememberme=$_POST['rememberme'];
            session_start();
            echo " and we will remember you too !";
            echo "<a href='loginFormDbase.php'><br />Click to try again</a>";
            $_SESSION['user'] = $user; // store session data
                                            }
                                    }
                }
                if ($loginOk==true) {echo "<br />good login";}
                else {header("Location: badlogindbase.html");}
        }
    else echo "Could not get the data from the database";
    }
?>


logoutdbase.php

<?php

session_start();
unset($_SESSION['user']);
echo "You are now logged out <br />";
echo "<a href='loginFormDbase.php'>Click to login again</a>";
?>



badlogindbase.html

<html>
    <head>
        <title>Bad Login</title>
        </head>
    <body>
   
        The credentials you supplied are incorrect
        <a href='loginFormDbase.php'>Click to try again</a>
    </body>
</html>

PHP Forms

Saturday, 16 April 2011

PHP Login Form

To create the login form itself was simple html. I decided to use POST rather then GET. The code is displayed below creates an html table with 3 columns and collects the user name and password from the user and places them in form variables. The form is then parse by checklogin.php which is shown further below.




The next image shows the output from the html code above :



The code  below shows the checklogin.php script. Lines 2 and 3 get the variables from the form using the $_POST. The next few lines create an associative array with sample logins and passwords.

The script then validates the credentials supplied by using array_search php function. If the credentials are correct the script will echo "Good login and pass" to the screen. If the credentials do not validate the user is taken back to index4.php which is the name of the main page which contains the form.



Adding the cookie proved to be very interesting. I spent several hours experimenting with setting, retreiving and deleting cookies as well as setting cookies with varying lifespans just to see how they work.

I modified index4.php to check if a cookie has already been set for this user. If it has then the form requesting the login and password is not shown. If a cookie was not previously set then the script will output the html to display the form.

index4.php

<html>
    <head>
        <title>Php Form</title>
        </head>
        <body>
   
    <?php if (isset($_COOKIE["user"])) {echo "Welcome " . $_COOKIE["user"] . "!<br />";}
                else {

echo "
<form name='login_form' method='post' action='checklogin.php'>
<table border='1' width='30%'><tr><td>
<table  width='100%' cellpadding='10' cellspacing='1'>
<tr><td colspan='2'><center>Login Form</center></td></tr>
<tr><td>Login Name</td><td><input name='user' type='text' id='user'></td></tr>
<tr><td>Password</td><td><input name='pass' type='password' id='pass'></td></tr>
<tr><td>Remember me</td><td>
<input type='checkbox' name='rememberme' id='rememberme' value='yes'></td></tr>
<tr><td colspan='2'><input type='submit' name='Submit' value='Login'></td></tr>
</table>
</td></tr></table>
    ";
    }
                        ?>
    </body>
</html>

The code below shows the modified checklogin.php script which now sets a cookie for this user if the login and password are validated. If the credentials supplied are incorrect, then the script redirects to a new page called badlogin.html which is also shown below.

Checklogin.php
<?php
    $user=$_POST['user'];
    $pass=$_POST['pass'];
   
    //create associative array for names and password
    $username['marcel'] = "abc123";
    $username['peter'] = "abc124";
    $username['sergio'] = "123abc";
    $username['marco'] = "111wwe";
    $username['andrew'] = "asd223";

    //Validate login and password
        //Check if password exists
        if (array_search($pass,$username)) {
            //check if corresponding login is correct
            if (array_search($pass,$username)==$user) {
            echo "Welcome, you are now logged in";       
           
            //Remember me was checked so we set the cookie
            if(isset($_POST['rememberme'])) {$rememberme=$_POST['rememberme'];
            echo " and we will remember you too !";
            setcookie("user", $user, time()+30);
            setcookie("pss", array_search($pass,$username), time()+30);
                                            }
                                                        }
                                            }
            else {header("Location: badlogin.html"); exit;}
    ?>

In the script above the cookie time is purposely set at only 30 seconds. During debugging, this avoided me having to manually clear cookies through the browser option when something went wrong.


badlogin.html

<html>
    <head>
        <title>Bad Login</title>
        </head>
    <body>
 
 The credentials you supplied are incorrect
 <a href='index4.php'>Click to try again</a>

    </body>
</html>

The screen shot below shows the modified form.



 The scripts where tested as follows :
  • Bad Login and password
  • Good Login and password
  • Good login, bad password
  • Bad login, good password
  • 'Remember me' checked
  • 'Remember me' not checked

The results showed that the scripts are working well under all the above conditions.


Changing to using Sessions
First of all I did some research about sessions. Once I figured out how they worked and I can now appreciate the major difference between them in that Cookies are client side while Sessions are server side. The question whether I should use Sessions or Cookies quickly came to mind. The major disadvantage of sessions is that they disappear when a user closes his browser window which means that anything stored in the session will be lost. Cookies are better in this respect as they persist regardless of what the user does with the browser unless he purposely deletes the cookie himself. Inherently cookies suffer from a related issue. If the user disables cookies in his browser then they obviously cannot be used. It seems that the best way would be to use a combination of both cookies and sessions on a practical project.
Sessions also have issues with clustered web servers when multiple web servers handle client requests for the same site. In the session is opened on another server the current one may not be aware of it.On the other hand, sessions offer more security as they are stored on the server and the users will not have access to them as they do for cookies. A user can easily modify the contents of a cookie as it is on his machine and being a simple text file he can easily edit the contents.

Research shows that it would be best to store sensitive data in a database and use sessions and cookies for less critical tasks.

The code below shows the new index5.php now using sessions. I have also added a new form so that the user is allowed to logout and clear the session.

index5.php

<html>
    <head>
        <title>Php Form</title>
        </head>
        <body>
    <?php
    session_start();
    if(isset($_SESSION['user'])) {echo "Welcome " . $_SESSION['user'] . "!<br />";
    echo "<form name='login_form' method='post' action='logout.php'>
            <input type='submit' name='Logout' value='logout'>";
    }
            else {
echo "
<form name='login_form' method='post' action='checkloginsessions.php'>
<table border='1' width='30%'><tr><td>
<table  width='100%' cellpadding='10' cellspacing='1'>
<tr><td colspan='2'><center>Login Form</center></td></tr>
<tr><td>Login Name</td><td><input name='user' type='text' id='user'></td></tr>
<tr><td>Password</td><td><input name='pass' type='password' id='pass'></td></tr>
<tr><td>Remember me</td><td>
<input type='checkbox' name='rememberme' id='rememberme' value='yes'></td></tr>
<tr><td colspan='2'><input type='submit' name='Submit' value='Login'></td></tr>
</table>
</td></tr></table>
    ";
    }

                        ?>
    </body>
</html>

The next code if for the checkloginsessions.php which now sets a session if the user checked the "remember me" checkbox in the index5.php form above.


checkloginsessions.php

<?php
    $user=$_POST['user'];
    $pass=$_POST['pass'];
   
    //create associative array for names and password
    $username['marcel'] = "abc123";
    $username['peter'] = "abc124";
    $username['sergio'] = "123abc";
    $username['marco'] = "111wwe";
    $username['andrew'] = "asd223";

    //Validate login and password
        //Check if password exists
        if (array_search($pass,$username)) {
            //check if corresponding login is correct
            if (array_search($pass,$username)==$user) {
            echo "Welcome, you are now logged in";       
           
            //Remember me was checked so we set the cookie
            if(isset($_POST['rememberme'])) {$rememberme=$_POST['rememberme'];
            session_start();
            echo " and we will remember you too !";
            echo "<a href='index5.php'><br />Click to try again</a>";
            $_SESSION['user'] = $user; // store session data
                                                        }
                                            }}
            else {header("Location: badloginsessions.html"); exit;}
    ?>

Finally the code below is the new logout page that clears the session followed by the badloginsessions.php script.

logout.php

<?php
session_start();
unset($_SESSION['user']);
echo "You are now logged out <br />";
echo "<a href='index5.php'>Click to login again</a>";
?>


badloginsessions.php
<html>
    <head>
        <title>Bad Login</title>
        </head>
    <body>
   
        The credentials you supplied are incorrect
        <a href='index5.php'>Click to try again</a>
    </body>
</html>

PHP - Starting at the beginning

Tuesday, 5 April 2011

Browser History
Although I must admit I did not find the in depth information on browser history particularly interesting, I happen to be old enough to have used most of the versions mentioned. I go right back to when Netscape was still for sale !

Although I appreciate the evolution of browsers, I find it surprising that most of them fail to adhere to the standards faithfully, inevitably causing countless cross-browser issues.

Php
I had been looking forward to learning php. I have been using applications that are built with Php in my work as a web designer for a number of years and have many times modified scripts to be able to achieve the desired results. These changes were however limited to simple changes as I never had the time and opportunity to learn php in a formal accademic way.

The course material was enough to get me going. I was amazed how similar the php scripting language is to other languages and I look forward to practicing this new scripting language.

Checking if php is working 
The most obvious way for testing if php is working on my local server is to actually write some php code in a basic php file and test it in a browser. So, to start off I created the following file :



Once the above php file is displayed in the browser, the date is in fact shown which means that the php has been processed by the local php installation as shown in the screen shot below.

A little reading also revealed that a special instruction exists that will prompt php to display information about the php installation. The instruction is phpinfo(). The result of adding this instruction to the above script resulted in the following result on the browser. (only a portion of the result has been displayed here)





Creating an Associative Array

I actually spent a lot of hours working with arrays, mainly not only because they are the subject of this part of the coursework but also because I had to get my hands dirty with some php. The experience was quite interesting and I think I have really started getting to grips with the syntax.

I spent some time trying out simple arrays and listing their contents and I ended up with the code below. 



The code first created the associative array called $user and populates it with some data. The html defines a simple table. The for each loop is then listing the contents of the array. I spent quite some time searching for a way to list the key value of an array rather than its contents. I finally realised that the array_search function could be used easily.








Alternate Row colors 

I then decided that I wanted to try coloring the rows of the table alternately in two different colors. I decided to use embedded CMS to achieve this.


The code above achieved the result shown here. I added CSS styling in the header that will later be used to colour the rows of the table.

I added the variable i that will be incremented with each iteration of the foreach loop. I introduced I to have a number to check for odd or even and use the css classes accordingly. The DIV or % operator is used to check if division by 2 leaves a remainder. In the row number is even there will be no remainder and the darker green row is displayed.

Finally I also added a new column to display the row number which is of course the value of i.



Difference Between Echo and Print
After reading up about the subject there seem to be very minor differences between Echo and Print. Echo claims to be marginally faster because it does not return a value but again the performance advantage is negligible. Echo can also accept multiple parameters whereas Print does not. Example :

<?php
          echo "Item 1", "Item 2";
     ?>