Here is where the honey pot comes in. A honey pot is a hidden form field in your form that human users cannot see, but bots that scour websites for form fields to autofill will see it and can enter a value for it. Then, when the bot tries to submit the form and spam your website, you can use form validation to stop any submits that has the honey pot filled in. Read more about honey pots here.
This lesson will give CodeIgniter users an easy way to use honey pots using the form validation class.
Setup
Set up a clean CI installation. Then go to your autoload file in your config folder.
Controller
Create a Controller named honey.php in your controllers folder.
Create the controller class, then add an index function that loads a view with the form you will create. In my case I named my view "form.php".
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Honey extends CI_Controller
{
function index()
{
$this->load->view('form');
}
}
View
Create a view that contains your form code.
Here is mine:
<html>
<body>
<h2>Generic Form</h2>
<form name="input" action="honey_submit" method="post">
<p>Name:
<input type="text" name="name" id="name" />
</p>
<p>Comment:
<input type="textbox" name="comment" id="comment" />
</p>
<input type="hidden" name="honeypot" id="honeypot" />
<p>
<input type="submit" />
</p>
</form>
</body>
</html>Notice the hidden input field named honeypot.
As you can see, the action submits it to a function in the controller called 'honey_submit'. So, create that function in your 'honey' controller file.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');(Bold is new code)
class Honey extends CI_Controller
{
function index()
{
$this->load->view('form');
}
function honey_submit()
{
}
}
Parse Data
To access the data that was sent:
function honey_submit()
{
$this->input->post('name');
$this->input->post('comment');
$this->input->post('honeypot');
}
Load Form Validation Class
function honey_submit()
{
$this->load->library('form_validation');
$this->input->post('name');
$this->input->post('comment');
$this->input->post('honeypot');
}
Set Validation Criteria
Let's make the name and comment required.
function honey_submit()Now, here is how you can use the Form Validation class to stop spambots and output an error message.
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('comment', 'Comment', 'required');
$this->input->post('name');
$this->input->post('comment');
$this->input->post('honeypot');
}
Using the Form Validation rule that calls a callback function, you can make a simple to see if the form is filled or not.
public function honey_submit()The 'set_rules' function needs three arguments: the input name from the form, any name used in the error message, and a function to use as the call back function.
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('comment', 'Comment', 'required');
$this->form_validation->set_rules('honeypot', 'Honeypot', 'callback_bot_test');
$this->input->post('name');
$this->input->post('comment');
$this->input->post('honeypot');
}
The name of the callback function are the characters after the 'callback_' part of the third argument of the 'set_rules' function, i.e. 'bot_test'.
Now we need to create the call back function in the 'honey' controller:
public function bot_test($input)The $input argument is whatever was sent from the hidden honeypot form field.
{
if ($input)
{
$this->form_validation->set_message('bot_test', 'No bots allowed!');
return FALSE;
}
else
{
return TRUE;
}
}
All we do is test that it exists. Then we set an error message.
Create 'form_submitted' View
<html>All we did here is check if there were any validation errors. If there were, we echo the error messages. If everything is OK, we tell the user that the form has been submitted and we echo out the name and comment that they submitted.
<body>
<p>
<?php if( validation_errors() ): ?>
<?php echo validation_errors();?>
<?php else: ?>
Form submitted!
<p>
Name:
<?php echo $name; ?>
</p>
<p>
Comment:
<?php echo $comment; ?>
</p>
<?php endif; ?>
</p>
<p>
</p>
</body>
</html>
Run Validation and Load the New View
This is a very important step. In your 'honey' controller and in the 'honey_submit' function, run the validation test.
public function honey_submit()This runs the validation tests and outputs any errors.
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('comment', 'Comment', 'required');
$this->form_validation->set_rules('honeypot', 'Honeypot', 'callback_bot_test');
$this->form_validation->run();
$this->input->post('name');
$this->input->post('comment');
$this->input->post('honeypot');
}
Now, load the view, passing the name and comment to the view.
public function honey_submit()Test and Finish
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('comment', 'Comment', 'required');
$this->form_validation->set_rules('honeypot', 'Honeypot', 'callback_bot_test');
$this->form_validation->run();
$data['name'] = $this->input->post('name');
$data['comment']= $this->input->post('comment');
$this->input->post('honeypot');
$this->load->view('form_submitted', $data);
}
Now, to test the honeypot, go the the 'form' view and change the html for the hidden input and give it a value:
Now try to submit the form.
<input type="hidden" name="honeypot" value="anyvalue" id="honeypot" />
You should get an error message 'No bots allowed!' .
Go back and delete the value section of the hidden input and you should be ready to go!
Conclusion
A honey pot is not 100%, but it does stop many of the bots.
A few good reasons to use the callback function to validate the input:
-It sets an error message automatically.
-You can do other things in the call back function, like record the IP address of a spammer.
Congratulations! You now know how to create a honey pot using CodeIgniter!