Getting Secured Using Mysqli

Introduction

The Mysqli class is a great help to working towards proper security when sending and pulling information from the database. It can stop injection attacks in their tracks and will allow you to specify data types allowing you to not let anything bad slip into the system.

In this article I will be going through the step by step approach to creating a query using prepared statements through MySQL. We are going to follow best practices and use the object oriented style to achieve a connection and gather our results.

Connecting to the database

The first thing that we will be doing is connecting to the database. Traditionally this should be done using an outside class to prevent an access to the connection information. The connection string will attempt to connect to the database and open up a persistent connection.

1
$this->connection = new mysqli('localhost','username','password','database');

Creating the prepared statement

The next thing that is required is for us to store the prepared statement. This should be attempted inside of an if statement. This way we can handle any errors appropriately.

1
2
3
4
5
6
7
8
9
10
$sql = "SELECT id, name, year FROM tbl_books WHERE name = ? AND year = ? LIMIT ?";
 
//store the prepared statement into the $stmt variable.
//note that the $stmt is a common naming for prepared statements.
if($stmt = $this->connection->prepare($sql))
{
 
}else{
	die(trigger_error($this->connection->error));
}

Wild cards

You probably noticed that the sql code has something new inside of it. This is the wild card for the sql statement and a ‘?’ is used to display it. This will allow us to bind variables in place of these questions marks and specify their data type.

Bind parameters

Bind parameters is the next step that takes place when there are wild cards inside of the sql statement. These allow us to force a data type into the format of our choosing. There are 4 data types that we can use.

‘I’ Integer
‘s’ String
‘d’ Decimal
‘b’ Blob

1
2
3
4
5
6
7
8
9
10
11
$sql = "SELECT id, name, year FROM tbl_books WHERE name = ? AND year = ? LIMIT ?";
 
//store the prepared statement into the $stmt variable.
//note that the $stmt is a common naming for prepared statements.
if($stmt = $this->connection->prepare($sql))
{
	//Now bind the data to the types.
	$stmt->bind_param('sii', $bookName, $bookYear, $limit);
}else{
	die(trigger_error($this->connection->error));
}

The above function that we just used will take a minimum of two arguments, the first to define the variable types and everything after that is a variable. Notice that all of the type declarations are in the same string. A common error for this piece of code is that you have an invalid amount of arguments being passed. Another error commonly given is that you cannot have data placed directly in the string. You need to reference variables.

1
2
//This is not allowed:
$stmt->bind_param('sii',"the php book", 4, 20);

Execution

Once we have properly set up our bindings we can execute the prepared statement and try to get a result from the database. As you can see in the code below; this can fail and an error message will be stored in case it does. This is why we are going to have it placed inside of an if statement.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$sql = "SELECT id, name, year FROM tbl_books WHERE name = ? AND year = ? LIMIT ?";
 
//store the prepared statement into the $stmt variable.
//note that the $stmt is a common naming for prepared statements.
if($stmt = $this->connection->prepare($sql))
{
	//Now bind the data to the types.
	$stmt->bind_param('sii', $bookName, $bookYear, $limit);
	//We will now execute the statement. This will throw an error if unsuccessful.
	if($stmt->execute())
	{
 
	}else{
		die(trigger_error($stmt->error));
	}
}else{
	die(trigger_error($this->connection->error));
}

Number of Rows

The next step in our quest for world domination is to store the results inside of the statement variable. This is going to let us make a call for the number of rows so we can handle the case of no rows being returned.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
$sql = "SELECT id, name, year FROM tbl_books WHERE name = ? AND year = ? LIMIT ?";
 
//store the prepared statement into the $stmt variable.
//note that the $stmt is a common naming for prepared statements.
if($stmt = $this->connection->prepare($sql))
{
	//Now bind the data to the types.
	$stmt->bind_param('sii', $bookName, $bookYear, $limit);
	//We will now execute the statement. This will throw an error if unsuccessful.
	if($stmt->execute())
	{
		//check the number of rows.
		$stmt->store_result();
		if($stmt->num_rows >= 1)
		{
 
		}else{
			echo 'Nothing was returned from the database.';
		}
	}else{
		die(trigger_error($stmt->error));
	}
}else{
	die(trigger_error($this->connection->error));
}
<pre>
<h2>Binding Results to Variables</h2>
The last thing that is required is binding the results and looping through the results. As you can see we are actually creating variables with this function and storing the information into them. The variables created are gathered from the select part of the statement. This means that we need to define the variables in the same order as the sql statement.
<pre lang="PHP" line="1">
$sql = "SELECT id, name, year FROM tbl_books WHERE name = ? AND year = ? LIMIT ?";
 
//store the prepared statement into the $stmt variable.
//note that the $stmt is a common naming for prepared statements.
if($stmt = $this->connection->prepare($sql))
{
	//Now bind the data to the types.
	$stmt->bind_param('sii', $bookName, $bookYear, $limit);
	//We will now execute the statement. This will throw an error if unsuccessful.
	if($stmt->execute())
	{
		//check the number of rows.
		$stmt->store_result();
		if($stmt->num_rows >= 1)
		{
			//bind the results
			$stmt->bind_result($id, $name, $year);
			//loop through the results.
			while($stmt->fetch())
			{
				echo "$name: $year<br>";
			}
		}else{
			echo 'Nothing was returned from the database.';
		}
	}else{
		die(trigger_error($stmt->error));
	}
}else{
	die(trigger_error($this->connection->error));
}

It is now time to run your code and gather the results using the fetch function. If you only have to return one row from the database then you can just use the fetch function outside of the while loop and it will allow you to pull the results and use the variables in the same way you would in the while loop.

Searching With %?% In a Prepared Statement

A while back when working on a project I learned that when using the wild card: ‘%’ in SQL with a prepared statement you are going to get an error message. This is because the prepared statement class has an issue with a wild card surrounding wild cards. ‘%?%’.

Because of this a simple sql query such as this is going to have issues pulling data from the database.

1
$sql = "SELECT * FROM tbl_comments WHERE comment LIKE %?% LIMIT 20";

Rather than attempt to get the above code to work you are going to need to take a separate approach and store the wild cards in with the search variable. This only takes one extra line of code and your search will be back up and running in no time at all.

1
2
$comment = '%'.$comment.'%';
$sql = "SELECT * FROM tbl_comments WHERE comment LIKE ? LIMIT 20";

Create Your Own PHP/AMF Data Service For Flex

This is a quick and short tutorial on how to create your own data services for flex to read. Also, note that in this tutorial we will be focussing on what a PHP Developer would be doing and not what a Flex Developer would do, we are not going to go over setting up data services or Flex, we are just going to be writing out classes.

Classes

The class is a rather simple thing to write out when focussing on creating an object that flex will be able to easily read. The trick to creating proper services is knowing what flex can do with your functions and your class.

The first thing to know is that flex is not going to be passing any values into the class and the class is not going to behave in a similar fashion to flex. This means that everything you do needs to operate on a function level.

The Construct

The construct is going to allow you to store information into the classes variables such as anything else and thus it is a good place to initialize and store a connection.

There isn’t a standard class declaration line within Flex and thus you cannot simply pass arguments through the parameters of the class.

The construct should look like this:

1
2
3
4
5
6
public function __construct()
{
    session_start();
    $this->connection = new mysqli('localhost','root','password','databasename');
 
}

Function Error Returns

Remember that the front end development team is going to need to know how to handle every situation of data that they receive and they will need to handle any scenario. Because of this you are going to need to return a status and message within the object in case anything goes wrong. A common standard is to simply store a boolean of if it worked as the first value returned. If the boolean is a false value then we know that the second object in the array is going to be an error message or an error code letting the front end know what went wrong.

Function Arguments

When setting up your arguments in the parameters of a function you are going to need to break away from pre setting the value of the argument with:

1
public function getMeta($metaName, $metaType = "video"){}

Values that are pre set in PHP do not show up in flex as an optional parameter.

Returning the Object

When using PHP/AMF as a data service it is good likely that you will need to return some rather complex objects to the front end team. The best way to pass data and allow them to use it is to store the information within an multi-dimensional array.

This means that when you use something like a prepared statement, you are going to need to handle the data and not just throw it back in a PHP array. If you throw back an unhandled mysqli array the front end team may kill you, especially if you have joins within your connection. This will force them to recreate an object from a singular one dimensional array.

Example of a custom Data Service.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public function pullVideoFromUser($userNid)
    {
        //Query the database and pull video information
        $sql = "SELECT t.name tour_name, t.tour_nid video_nid, tm.created tour_created, tm.modified tour_modified, tm.viewcount tour_viewcount
            FROM tbl_user_video ut
            INNER JOIN tbl_video t ON ut.video_nid = t.video_nid
            INNER JOIN tbl_video_meta tm ON tm.video_nid = tu.video_nid
            WHERE u.user_nid = ?";
 
        $videoReturn = array();
        if($stmt = $this->connect->prepare($sql))
        {
            $stmt->bind_param('i', $userNid);
            $stmt->execute();
            $stmt->store_results();
            if($stmt->num_rows >= 1)
            {
                $stmt->bind_results($key, $name, $nid, $created, $modified, $viewcount);
                while($stmt->fetch())
                {
                    //create an object holding the appropriate information
                    $videoReturn[] = array('status' => 1,'key' =>$key, 'name' => $name, 'nid' => $nid, 'created' => $created, 'modified' => $modified, 'viewcount' => $viewcount);
                }
            }else{
                //Store a status of false and return an error message within the object.
		$videoReturn[] = array('status' => 0, 'message' => 'There was an issue returning the video.')
	    }
        }else{
            //Store a status of false and return an error message within the object.
	    $videoReturn[] = array('status' => 0, 'message' => $this->connection->error);
	}
        //return the object
        return $videoReturn;
 
    }

Stop Direct Page Access With PHP

There are a few ways to stop direct access of a page. I will go over a few simple techniques that will help out those of you that are just getting into PHP.

Method number 1

Assuming that all of your pages require a function that was made by yourself and is brought in from another page. ie: “require_once(‘functions.php’);” then we can just do a simple check for the function.

1
2
3
4
5
6
<?php
if(!function_exists('yourfunction'){
    header('/index.php');
    die('Page cannot be accessed directly.');
}
?>

Method 2

This way of checking for the page is usually a good idea for pages that handle process information. Whether that information is handled through get or post you will still be able to use this form factor.

1
2
3
4
5
6
<?php
if(!isset($_GET['id']){
    header('location: index.php');
    die('You cannot access this page directly.');
}
?>

Just a little note for using GET and POST information. PHP is a lot more strict then people will give it credit for and this is because most of the time the errors are small and turned off. If you were to take a look at your error log you will get an entry whenever a page loads a variable with GET or POST and said GET or POST does not exist. For this reason you should check if it is set prior to loading the content into any variable.

Summary of Methods

In this short tutorial we have gone over how to prevent page access. Although these are good clean ways to prevent users from seeing pages that you don’t want them to see it is often easier to modify your HTACCESS page to prevent a page from being access directly a quick way would be do add this your .htaccess file.

1
2
3
4
<files process.class.php>
 order allow,deny
 deny from all
</files>

Check Email Function PHP

Just recently created this piece of code for dream in codes new framework.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function check_email($email, $rec = 'MX'){
//	1. clean up email
	$email = trim($email);
 
	$v1 = strstr($email, ' ');
	if($v1 != null){
		echo 'There is a space.';
		return false;
	}
//	2. check if it has the proper characters
	list($start, $domain) = split("@", $email);
	if(isset($start) && isset($domain) && eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email) > 0){
		echo  "good<br>";
 
		// 3. split email into two and check dns
		if(!empty($domain)) {
			if( $rec == '' ) $rec = "MX";
			exec("nslookup -type=$recType $hostName", $result);
			// check each line to find the one that starts with the host
			// name. If it exists then the function succeeded.
			foreach ($result as $line) {
				if(eregi("^$hostName",$line)) {
					echo "hostname is good";
					return true;
 
				}
		}
		// otherwise there was no mail handler for the domain
		return false;
	}return false;
    }return false;
}

The code isn’t exactly rocket science and thus I won’t be leaving you with any more information on this function.

Creating a Multi-Page Site From One Page Using GET

Creating a Multi-Page Site From One Page Using GET from Caleb Jonasson on Vimeo.

Source Code

Download Zip File

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
 
$t = $_GET['t'];
 
if($t == 'contact'){
	echo 'contact page';
}else if($t == 'about'){
	echo 'about page';
}else{
	echo 'index page';
	echo '<br> <a href="?t=about">about</a>';
}
?>

Adding The ‘Like’ Button to WordPress

Plugins can often slow down WordPress’ load times so it best to build into the theme if possible. This is why we are going to run through a quick tutorial were we will be adding a like button to a WordPress theme.

Getting The Like Button Code

The first thing that you are going to need is the like button code itself. I will be providing it for you but if you would like to go and get it yourself there are some more customization options by going to the Facebook developer page.

1
2
3
<iframe src="http://www.facebook.com/widgets/like.php?href=http://skorg.org/"
scrolling="no" frameborder="0"
style="border:none; width:480px; height:80px"></iframe>

Now we need to find a good place for our like button to go. I would recommend placing it below the post so once the user has completed reading through the article they can then like it. If you put it above there is a chance that they are going to miss the button and just move on.

The button is going to be added to the bottom of the post on the single.php page that you can find in your theme directory. Just go to ‘/wp-content/themes/your-theme-name/single.php’.

Now we will simply add the code in and tweak a couple of things so it will work on each page.

1
2
3
<iframe src="http://www.facebook.com/widgets/like.php?href=<?php the_permalink()?>"
scrolling="no" frameborder="0"
style="border:none; width:480px; height:80px"></iframe>

Adding the Code to Your Theme

The code will be inserted and your single page should look something more like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="clear"></div>   
	<div class="meta-entry clear">
		<?php
			//full post
        	the_content(__('read more...', 'skorg-cwd1'));
        ?>
        <iframe src="http://www.facebook.com/widgets/like.php?href=<?php the_permalink()?>"
        scrolling="no" frameborder="0"
        style="border:none; width:480px; height:80px"></iframe>
 
       	<?php edit_post_link(__('Edit!', 'skorg-cwd1')); ?>
        <?php wp_link_pages(); ?>
    </div><!--end entry-->
	<div class="post-footer">

Notes

When inserting the post just look for something call the_content() then simply past the code bellow this and your like button should work without a flaw.