UPDATE 2008-10-24 This guy has an updated post for Zend_Captcha. Mine is old an out-dated.
Here is how to create a simple Captcha image with the Zend Framework.
I have created this controller named: ImagegeneratorController. The job of this controller is to display images – whether from a database blob or in this case, an image created on the fly.
< ?php class ImagegeneratorController extends Zend_Controller_Action { public function init() { $this->_helper->viewRenderer->setNoRender(); } public function generatecaptchaAction() { //Let's generate a totally random string using md5 $md5_hash = md5(rand(0,999)); //We don't need a 32 character long string so we trim it down to 5 $security_code = substr($md5_hash, 15, 5); $_SESSION['captcha_code'] = $security_code; //Set the image width and height $width = 100; $height = 20; //Create the image resource $image = ImageCreate($width, $height); //We are making three colors, white, black and gray $white = ImageColorAllocate($image, 255, 255, 255); $black = ImageColorAllocate($image, 0, 0, 0); $grey = ImageColorAllocate($image, 204, 204, 204); //Make the background black ImageFill($image, 0, 0, $black); //Add randomly generated string in white to the image ImageString($image, 3, 30, 3, $security_code, $white); //Throw in some lines to make it a little bit harder for any bots to break ImageRectangle($image,0,0,$width-1,$height-1,$grey); imageline($image, 0, $height/2, $width, $height/2, $grey); imageline($image, $width/2, 0, $width/2, $height, $grey); //Tell the browser what kind of file is come in header("Content-Type: image/jpeg"); //Output the newly created image in jpeg format ImageJpeg($image); } } |
Now, anywhere in my view file (.phtml), I can do this to display the image:
... <img src="http://blog.ekini.net/wp-admin/%3C?php%20echo%20$this-%20/%3EbaseUrl.%27/imagegenerator/generatecaptcha%27%20?%3E" /> ... |
That’s about it. To check if there is are any errors, try to http://yoursite.com/imagegenerator/generatecaptcha – it should display the image. From there you can debug for errors if there are any.
*Update*
Apparently, I forgot to store $security_code variable into a session variable. This value will be used to verify if the user has entered the correct security code after submitting the form.
The test form: < form action="/path/to/controller/action" method="post"> Captcha Code: <img src="< ?=$this-/>baseUrl?>/imagegenerator/generatecaptcha" /> Enter Code Here: <input name="entered_coded" type="text" /> <input value="Submit" type="button" /> |
Now, in the controller that will handle the form, you will have something like this:
... public function handlecaptchaAction() { $entered_captcha = /*get from POST*/; if ($entered_captcha != $_SESSION['captcha_code']) { echo 'You are a bot!!!'; } //rest of the code here... } ... |
Resources: http://www.webcheatsheet.com/php/create_captcha_protection.php
Thanks to: DanielF and Booster in #zftalk
Post your comments / corrections below. Thanks!
Update:
Hi, just a suggestion, to update your code… For example when a user opens 2 posts with the same image, he won’t be able to post the first opened article (or what ever). I suggest naming the session variable ‘captcha_code’.post_id. And to pass the variable, use /imagegenerator/generatecaptcha/post_id/id.
BY: Tomas on 30 May 2008 at 4:38 pm
Fantastic! Just what I have been looking for.
One suggestion, would it not be more desirable to build the captcha processor into a model? That way the code could easily be integrated with other form processing.
Thanks Pharalia. Hmmm I haven’t thought of it that way. I guess you could put it in a model, but I’m thinking that models in MVC do databases. That is why I created a new controller for it. But I say, whatever works for you, works for me as well
Build a captcha image and show it is easy.
But how to integration it ZF is difficulty more.
$form->addElements(‘captcha’)
@Emeric: This tutorial came out before Zend_Form was included in the 1.5 release. I do not know how to do a captcha image using Zend_Form yet
Sorry but this doesn’t work for me. I’m using ZF 1.5 but when i call the action its return only a string that is the alt html attributes of the image. Your code looks works out of zf (i try it in a single script).
Luca, please make sure that you have placed no-render on your code:
$this->_helper->viewRenderer->setNoRender();
… and garbage comes out of your browser, then it isn’t displaying the proper headers. You can do so by putting this line:
header(“Content-Type: image/jpeg”);
I have a working example here:
http://mylyricsfinder.com/imagegenerator/generatecaptcha
Hi, just a suggestion, to update your code… For example when a user opens 2 posts with the same image, he won’t be able to post the first opened article (or what ever). I suggest naming the session variable ‘captcha_code’.post_id. And to pass the variable, use /imagegenerator/generatecaptcha/post_id/id.
Hi Tomas,
Thank you for your suggestion. I am updating the post above with your suggestion so that it will be easier for the other readers.
Thanks so much! ^_^
Nice tutorial, but your code didn’t work for me. On my browser display: “http://localhost/imagegenerator/generatecaptcha”. No image displaye. I’ve copy your code, to my app, any suggest for my problem? Thx. (Sory for my bad English).
hi sangbima,
Can you http://paste2.org your code?
Are you getting error messages? Please provide more details. I would be glad to help you out.
Thanks,
Wenbert
This my Controller:
class ImagegeneratorController extends Zend_Controller_Action {
public function init()
{
$this->_helper->viewRenderer->setNoRender();
}
/**
* The default action – show the home page
*/
public function generatecaptchaAction() {
//Let’s generate a totally random string using md5
$md5_hash = md5(rand(0,999));
//We don’t need a 32 character long string so we trim it down to 5
$security_code = substr($md5_hash, 15, 5);
$_SESSION['captcha_code'] = $security_code;
//Set the image width and height
$width = 100;
$height = 20;
//Create the image resource
$image = ImageCreate($width, $height);
//We are making three colors, white, black and gray
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$grey = ImageColorAllocate($image, 204, 204, 204);
//Make the background black
ImageFill($image, 0, 0, $black);
//Add randomly generated string in white to the image
ImageString($image, 3, 30, 3, $security_code, $white);
//Throw in some lines to make it a little bit harder for any bots to break
ImageRectangle($image,0,0,$width-1,$height-1,$grey);
imageline($image, 0, $height/2, $width, $height/2, $grey);
imageline($image, $width/2, 0, $width/2, $height, $grey);
//Tell the browser what kind of file is come in
header(“Content-Type: image/jpeg”);
//Output the newly created image in jpeg format
ImageJpeg($image);
}
}
Then My View:
–
img src=”imagegenerator/generatecaptcha” alt=”captcha”
–
No error message on My Display.
Hi sangbima,
I made an error on my post. Please do this in you view:
Security Code: < img src="< ?php echo $this->baseUrl.’/imagegenerator/generatecaptcha’ ?>” />
You have to echo it with the baseUrl.
Still not working for me.
hmmm strange. can you give me a “view source” of your < img > tag?
< img src=”baseUrl.’/imagegenerator/generatecaptcha’?>” />
I try to write like this:
, still didn’t work.
sangbima, nope that won’t work.
$this->baseUrl is supposed to display your base URL. The baseUrl should be something like: http://localhost/appname
Try this:
In your controller, do this:
$this->view->baseUrl = $this->_request->getBaseUrl();
Then in you .phtml file, you should be able to use $this->baseUrl
The IMG tag in your .phtml / view file should look something like this:
< img src=”baseUrl ?>’/imagegenerator/generatecaptcha’?>” />
the output should be like:
< img src=”http://localhost/appname/imagegenerator/generatecaptcha” />
The syntax in your .phtml is totally wrong. ^_^
Hi,
sangbima try changing $_SESSION[‘captcha_code’] = $security_code; in your controller. Those quote marks should be ‘ or “. I had the same problem and that solved it.
Good tutorial..
I have tried the coding and its working
The question is how to make a bigger font size, I have tried but it allow only 5 as maximum font size.
ImageString($image, 5, 30, 3, $security_code, $white);
Didn’t work for me either.
I just get (in safari) a question mark so he doesn’t find an image.
Saving the captcha picture is working, so I just overwrite the captcha picture and save it, and show this image.
@Peter Hons, maybe you can Paste2.org your code so that we can take a look at it?
Hello,
I am using this code in a sample test I am working on.
In the application the Layout is used .But when the layout is enabled the image is not generated.Without layout image is generated.
What should I do?
@Sudarshan, I am not sure. I have not tested this with the layouts. But I am thinking that you need to “disable” layouts for the ImagegeneratorController and its actions because the HTML tags in the Layout will be rendered with the images.
Instead of outputting the image, the Layout interferes with the HTML tags, etc. because the layout is parsed first before the action (the image) is rendered.
Thanks.
Do you like Zend_Captcha ?
Snowcore, I haven’t used Zend_Captcha yet…
anyone can show how to use the internal Zend_Captcha to generate an image?
someone can you explain for me how can generate the code the captcha with zend framework 1.6
thanks
I’m getting this error
“Call to undefined function ImageCreate()”
How do I include this function?
Thanks
@edazevedo make sure that your ImagegeneratorController is working. You do not have to “include” this function. It simply works once you have your Zend Framework setup in you application. See http://framework.zend.com/manual/en/zend.controller.html for more information.
I’ve got my zend framework up and running
Controllers are working ok.
Isn’t ImageCreate() a function from the PHP GD-extension, or other?
It just don’t seem to be from the Zend Framework library.
Thanks
Problem solved. I’ve just installed the PHP GD-extension and it started working.
I’m using ubuntu, so I get the package with:
sudo apt-get install php5-gd
and restarted my apache server:
sudo /etc/init.d/apache2 restart
and that’s it.
Hi, All
Here in this code Header is defined like this
header(“Content-Type: image/jpeg”);
So it will might not give you the result
Try this header instead of :
$this->_response->setHeader(‘Content-Type’, ‘image/jpeg’);
Thanks alot – great tutorial!
@Sudarshan You can disable layout this way: $this->_helper->layout->disableLayout();
Hi,
Nice tutorial, thanks for sharing with us. I got it working. But the controller where I am using this is not recognizing the SESSION created in another (Image) controller.
I got this error:
Notice: Undefined index: captcha_code in C:AppServwwwsuper2controllersTestController.php on line 42
Can you please help me to solve this problem.
Thanks,
Jyotsna.
@Jyotsa, make sure you have defined $_SESSION['captcha_code'].
Try to do a $_SESSION['captcha_code'] = NULL;
See if that works. If not, paste2.org your code and email me the link so that I can take a look at it.
hi… i m unable to see the captcha image….
no captcha code is here…..
i just do thses things nothing else….
1.
my contoller:
_helper->viewRenderer->setNoRender();
}
public function generatecaptchaAction()
{
//Let’s generate a totally random string using md5
$md5_hash = md5(rand(0,999));
//We don’t need a 32 character long string so we trim it down to 5
$security_code = substr($md5_hash, 15, 5);
$_SESSION['captcha_code'] = $security_code;
//Set the image width and height
$width = 100;
$height = 20;
//Create the image resource
$image = ImageCreate($width, $height);
//We are making three colors, white, black and gray
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$grey = ImageColorAllocate($image, 204, 204, 204);
//Make the background black
ImageFill($image, 0, 0, $black);
//Add randomly generated string in white to the image
ImageString($image, 3, 30, 3, $security_code, $white);
//Throw in some lines to make it a little bit harder for any bots to break
ImageRectangle($image,0,0,$width-1,$height-1,$grey);
imageline($image, 0, $height/2, $width, $height/2, $grey);
imageline($image, $width/2, 0, $width/2, $height, $grey);
//Tell the browser what kind of file is come in
header(“Content-Type: image/jpeg”);
//Output the newly created image in jpeg format
ImageJpeg($image);
}
}
2: my view file:
3: my form:
Captcha Code:
<img src=”baseUrl();?>/imagegenerator/generatecaptcha” />
Enter Code Here:
PLEASE HELP ME GUYS…..I am not having Captcha image….and sumbit button not working????
@navdeep try to var_dump the baseUrl(). make sure that works.
You should see an image when you go to: http://mysite.com/imagegenerator/generatecaptcha
Pingback: Zend Framework és Captcha – egyszerű céges oldal (Demo Kft) – Kapcsolat űrlap – biztonság IV.rész « Simon András blogja
Nice code!I try this and it’s work fine in zf 1.5, but not work in zf 1.8. Can you give me a suggestion? Thanks !
hi, thnx for nice tutor, i got the same bug as some users here, in my case problem was that i use layout in my application. Here is updated init function() that solves that.
public function init() {
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
}
You will know that you have the same problem, if you call your url of image (which now returns only title of url itself) in img html tag, then move the area which should be the image to your desktop, it will appear as html file, and when you open it,you can see bad bug content.
Thank you for this. It helped me a lot.
i have got the same problem
to see ur captcha you must change header position like this
public function generatecaptchaAction()
{
//Tell the browser what kind of file is come in
header(“Content-Type: image/jpeg”);
//Let’s generate a totally random string using md5
$md5_hash = md5(rand(0,999));
//We don’t need a 32 character long string so we trim it down to 5
$security_code = substr($md5_hash, 15, 5);
$_SESSION['captcha_code'] = $security_code;
//Set the image width and height
$width = 100;
$height = 20;
//Create the image resource
$image = ImageCreate($width, $height);
//We are making three colors, white, black and gray
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$grey = ImageColorAllocate($image, 204, 204, 204);
//Make the background black
ImageFill($image, 0, 0, $black);
//Add randomly generated string in white to the image
ImageString($image, 3, 30, 3, $security_code, $white);
//Throw in some lines to make it a little bit harder for any bots to break
ImageRectangle($image,0,0,$width-1,$height-1,$grey);
imageline($image, 0, $height/2, $width, $height/2, $grey);
imageline($image, $width/2, 0, $width/2, $height, $grey);
//Output the newly created image in jpeg format
ImageJpeg($image);
}
Great post Tomas!
This is the simplest code to use Captcha..
Sorry but you missed one line in function init():
$this->_helper->layout()->disableLayout();
Which make me worry for some hours!
i think the code should add
…………
imagejpeg($image,null,75);
imagedestroy($image);
exit;
}