Archive for the ‘PHP’ Category

Gracefully handling errors in php using advanced techniques

Saturday, October 11th, 2008

There are a few ways in which you can handle errors in PHP. You can do the not so smart thing and just turn them off altogether using

PHP Code
1
2
3
ini_set('error_reporting',0);
//or
error_reporting(0);

However this is not a good idea, and should never happen. If you want to hide all of your errors, you can set it so that you have them hidden, but log them to a file instead

PHP Code
1
2
ini_set('display_errors','off');
ini_set('log_errors','on');

That will then log all of your errors to your server error log by default. If you wish to set the log to a different file you can do so by using

PHP Code
1
ini_set('error_log','/path/to/your/error.log');

and that will log all of your errors to error.log in the /path/to/your/ directory.

Another option is to use a custom function to handle all errors. This can be useful should you wish to log all of your errors to a database so that you can use queries to view errors instead. The way that we tell PHP that we want to handle the errors ourselves is to use the set_error_handler() function and pass the name of the function we want to handle the errors.

PHP Code
1
set_error_handler('custom_error_func');

Then we make a function to handle the errors. For example if you wanted to add the error to your database table it would look something like this

PHP Code
1
2
3
4
5
6
7
8
9
10
11
12
13
function custom_error_func($errno, $errmsg, $filename, $line, $context)
{
    // Create query - NOTE: This is using the mressf() function that I created available at
    // http://www.jaygilford.com/php/sprintf-and-mysql_real_escape_string-all-in-one-function/
    $query = mressf("INSERT INTO `errors` VALUES(NULL,'%s','%s','%s','%s','%s')",
                    $errno,
                    $errmsg,
                    $filename,
                    $line,
                    $context);
    //run query
    mysql_query($query);
}

If you wish to have any of the above ini_set() functionalities set permanently on your server, you may be able to if you have access to either the php.ini file or your .htaccess allows you to make php changes you can do so quite simply. For the php.ini file, simply search the file for display_errors for example and modify the value in there. If you are using .htaccess, you may be able to use the php_flag or php_value settings to modify the data. For more information on setting values this way, see here

sprintf and mysql_real_escape_string all in one function

Wednesday, October 8th, 2008

Well as many php developers will know, there is the arduous task of having to sanitize all of your data before actually being able to add it to your queries for running in MySQL. So I decided to make a small function that would basically be a clone of the sprintf function, with the added bonus of running the mysql_real_escape_string on all of the arguments passed to it

PHP Code
1
2
3
4
5
6
7
8
9
10
11
function mressf()
{
    $args = func_get_args();
    if (count($args) < 2)
        return false;
    $query = array_shift($args);
    $args = array_map('mysql_real_escape_string', $args);
    array_unshift($args, $query);
    $query = call_user_func_array('sprintf', $args);
    return $query;
}

You would then call it as you would with your regular sprintf function such as

PHP Code
1
echo mressf("SELECT * FROM `table` WHERE `name` = '%s' AND `password` = '%s'", 'username', 'pass');

which would return

SELECT * FROM `table` WHERE `name` = 'username' AND `password` = 'pass'

random redirects to sites with php script

Sunday, September 28th, 2008

I was asked to create a script that would produce an even number of visits to each of three sites. I decided that I would skip the checking of making sure each site had a fair amount and instead generate the url randomly, since by the laws of averages, the number of redirects to each should work out to be roughly even over the course of time. So, onto the script…

PHP Code
1
2
3
4
5
6
7
$sites = array(
'http://www.google.com/',
'http://www.msn.com/',
'http://www.yahoo.com/'
)
header('Location: '.$sites[array_rand($sites)]);
die();

As you can see, it’s very simple. It is also open for you to add more sites into the $sites array
If you need any help with this or any other code that I have written, contact me via the address in the About page

creating random activation links for downloads

Monday, July 21st, 2008

This article is intended for advanced users. It explains the principles behind creating a download activation link that is completely random and will stay active for 48 hours after a payment through paypal for example is made

You are going to need two files for this to work. The first is going to be the file that creates the link, adds it to a database table and sends the link via email. The second is the file that will parse all incoming links for the download script, and if the link is verified as being correct it will proceed to allow a user to download the file

NOTE: I will not be describing the intricacies of email or the payment via paypal in this article, merely the methods by which you will need to follow in order to achieve a link creation and verification

Part 1 – Creating the activation key

This should go in your script after your payment has been accepted. I have also not included mysql connection details and function either ie the mysql_connect function or the close function. This is in case you are working with multiple databases whilst doing this

The rand_text function is explained here

PHP Code
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
function rand_text(   $min = 10,
                      $max = 20,
                      $randtext = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' )
{
    if($min < 1) $min=1;
    $varlen = rand($min,$max);
    $randtextlen = strlen($randtext);
    $text = '';
 
    for($i=0; $i < $varlen; $i++)
    {
        $text .= substr($randtext, rand(1, $randtextlen), 1);
    }
    return $text;
}
 
// Some setup values
$tblname = 'tbl_keys'; #table name in database
$keymin = 50; #mimumum key length
$keymax = 80; #maximum key length
$keyurl = 'http://www.domain.com/activate.php?key='; #domain to add key to
$datefield = 'added'; #date field to put insert date into
$keyfield = 'key'; #activation key field
$mailto = 'email@example.com'; #email to send link to
$mailsubject = 'Download activation link'; #email subject line
 
// create random string
$key = rand_text($keymin,$keymax);
// add it to database with current date
$query = "INSERT INTO
              `{$tblname}`
          SET
              `{$keyfield}` = '{$key}',
              `{$datefield}` = NOW()";
mysql_query($query);
 
//Add key to activation url template
$keyurl .= $key;
 
//Create mail message
$message = "Below is your activation link. You have 48 hours in which to use it, after which it will expire
 
{$keyurl}
 
Your website name
http://www.yourdomain.com/";
 
//Mail activation key to the user
mail($mailto, $mailsubject, $message);

So you now have an emailing key generator. Next you will need to make a table in your database (remember to change tbl_keys to the one assigned to $tblname above)

MySQL Code
1
2
3
4
5
6
CREATE TABLE `tbl_keys` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `added` DATETIME NOT NULL,
  `key` VARCHAR(100) NOT NULL,
  PRIMARY KEY  (`id`)
)

That’s a basic example just for this tutorial. For yours you can add other information such as the download id for the link (ie what the user will download upon clicking the link) plus any other info you wish to store with each link

Part 2 – Creating the key verification and download script

Now we need to create the activate.php script that was in the $keyurl above, to take the key and verify that the key hasn’t expired

PHP Code
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
//Verify a key has been entered
if(!isset($_GET['key']) || strlen($_GET['key'] == 0))
{
	//Redirect to site homepage
	header('Location: /index.php');
}
 
// Some setup values (same as first script)
$tblname = 'tbl_keys'; #table name in database
$datefield = 'added'; #date field to put insert date into
$keyfield = 'key'; #activation key field
 
//Assign key to shorter variable for ease of use
$key = $_GET['key'];
 
//////////////////////////////////////////////////
//CONNECT HERE TO DATABASE USING mysql_connect()//
//////////////////////////////////////////////////
 
//Remove any nasty characters that might cause SQL Injection
//(removes any characters except a-z and 0-9)
$key = preg_replace('/[^A-Za-z0-9]/','',$key);
 
//Set up query to run (The 172800 is 48 hours in seconds)
$query = "SELECT
              *
          FROM
              `{$tblname}`
          WHERE
              (unix_timestamp(NOW()) - unix_timestamp(`{$datefield}`)) < 172800
          AND
              `{$keyfield}` = '{$key}'";
 
//Run the query
$res = mysql_query($query);
 
//Check that a result was found
if(mysql_num_rows($res) < 1)
{
	//Key not found
	die('
<h1>ERROR: KEY INVALID/EXPIRED</h1>
');
}else{
	////////////////////////////////////////////////////////
	//INSERT YOUR CODE HERE FOR WHAT HAPPENS IF THE KEY IS//
	//CORRECT AND HASNT EXPIRED                           //
	////////////////////////////////////////////////////////
}

All that’s left is for you to add your mysql connection and also your code for what to do if the link is valid in the above code

If you have any suggestions on how to improve it or any questions, just drop me a line

php random string generator function

Wednesday, July 16th, 2008

Many people need a random string for things such as salts, activation keys and new passwords. Here’s a simple but versatile function to return a random string

PHP Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function rand_text(   $min = 10,
                      $max = 20,
                      $randtext = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' )
{
    if($min < 1) $min=1;
    $varlen = rand($min,$max);
    $randtextlen = strlen($randtext);
    $text = '';
 
    for($i=0; $i > $varlen; $i++)
    {
        $text .= substr($randtext, rand(1, $randtextlen), 1);
    }
    return $text;
}

To call this function, you can simply use rand_text() which will return a random alphanumeric string between 10 and 20 characters long. You can also specify a min and max length, and can also specify the string of characters that can be used in the random string. For example

PHP Code
1
echo rand_text(5,8,'abcdef0123456789');

will output a random hex value between 5 and 8 characters in length such as 2fe4e1