Trying to create captcha

Discussion in 'PHP' started by Tom12361, Aug 14, 2009.

  1. #1
    Hi,
    So, here is captcha.php file:
    
    <?php
    session_start();
    
    $width  = 120;
    $height =  40;
    $length =   5;
    
    $baseList = '123456789qwertyuiopasdfghjklzxcvbnm';
    
    $code    = "";
    $counter = 0;
    
    $image = @imagecreate($width, $height) or die('Cannot initialize GD!');
    
    for( $i=0; $i<10; $i++ ) {
       imageline($image, 
             mt_rand(0,$width), mt_rand(0,$height), 
             mt_rand(0,$width), mt_rand(0,$height), 
             imagecolorallocate($image, mt_rand(150,255), 
                                        mt_rand(150,255), 
                                        mt_rand(150,255)));
    }
    
    for( $i=0, $x=0; $i<$length; $i++ ) {
       $actChar = substr($baseList, rand(0, strlen($baseList)-1), 1);
       $x += 10 + mt_rand(0,10);
       imagechar($image, mt_rand(3,5), $x, mt_rand(5,20), $actChar, 
          imagecolorallocate($image, mt_rand(0,155), mt_rand(0,155), mt_rand(0,155)));
       $code .= strtolower($actChar);
    }
       
    header('Content-Type: image/jpeg');
    imagejpeg($image);
    imagedestroy($image);
    
    $_SESSION['securityCode'] = $code;
    $a='mytextisgood';
    
    ?> 
    
    Code (markup):
    And here is index.php file:
    
    <?php session_start(); ?>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "DTD/xhtml1-transitional.dtd">
    <html>
    <head>
       <title>Captcha demo</title>
    </head>
    <body>
    <?php
       if (isset($_POST['submitBtn'])){
          $secCode = isset($_POST['secCode']) ? strtolower($_POST['secCode']) : "";
          if ($secCode == $_SESSION['securityCode']) {
             echo "<p>The result code was valid!<br/></p>";
             unset($_SESSION['securityCode']);
             $result = true;
          }
          else {
             echo "<p>Sorry the security code is invalid! Please try it again!</p>";
             $result = false;
          }
       }
       
       if ((!isset($_POST['submitBtn'])) || (!$result)){
    ?>      
          <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" >
            <table width="400">
              <tr>
                <td>Security code: 
                   <input class="text" name="secCode" type="text" size="10" />
                </td>
                <td>
                   <img src="captcha.php" alt="security code" border="1" />
                   <? echo $_SESSION['securityCode']; ?>
                   <? echo $a;?>
                </td>
              </tr>
              <tr>
                <td colspan="2" align="center"><br/>
                   <input class="text" type="submit" name="submitBtn" value="Send" />
                </td>
              </tr>
            </table>  
          </form>
    <?php
       } 
    ?>      
    
    Code (markup):
    And here is a few questions:
    1) When I load index.php file, why the text 'mytextisgood' doesn't appear on the browser? I write echo $a; but still, it gives me no results?
    2) Does <img src="captcha.php" alt="security code" border="1" /> work like include("captcha"); ? And why when I use include("captcha"); it gives me an error?
    3) And the last question, why <? echo $_SESSION['securityCode']; ?> writes in the browser only the previous symbols even I put <? echo $_SESSION['securityCode']; ?> before <img src="captcha.php" alt="security code" border="1" />, but not the recent one ?

    I hope you understood what I wanted to ask and I'll be grateful if you help me, thanks.
     
    Last edited: Aug 14, 2009
    Tom12361, Aug 14, 2009 IP
  2. Gray Fox

    Gray Fox Well-Known Member

    Messages:
    196
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    130
    #2
    The file 'captcha.php' sets $_SESSION['securityCode'] to generated security code and displays it on the captcha image requested via your BROWSER, not other PHP script. In other words, file 'captcha.php' shouldnt be included in any other PHP script, it should only be requested via HTTP, and within <img> tag, like <img src="captcha.php"/>.

    Try running 'captcha.php' and you'll see what I'm talking about. After that, only $_SESSION['securityCode'] changes and that variable can be accessed by any other script on the same site.
     
    Gray Fox, Aug 14, 2009 IP
  3. Tom12361

    Tom12361 Active Member

    Messages:
    442
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    58
    #3
    I still don't get, why $_SESSION['securityCode'] shows only previous image, but not the recent one
     
    Tom12361, Aug 14, 2009 IP
  4. Gray Fox

    Gray Fox Well-Known Member

    Messages:
    196
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    130
    #4
    Because this is how your script works:

    Parse PHP (index.php) -> Print HTML (also from index.php) -> Client requests CAPTCHA (from captcha.php, because the image source points to that file) -> CAPTCHA is shown and $_SESSION['securityCode'] is set (in captcha.php)

    So basically, HTTP request for CAPTCHA image (generated in captcha.php) is done after PHP (in index.php) is done with parsing, so thats why $_SESSION variable is set when you request that image via HTTP.
     
    Gray Fox, Aug 14, 2009 IP
  5. kblessinggr

    kblessinggr Peon

    Messages:
    539
    Likes Received:
    13
    Best Answers:
    0
    Trophy Points:
    0
    #5
    You could save yourself a heck of time, and increase effectiveness using something like reCaptcha http://recaptcha.net/
     
    kblessinggr, Aug 14, 2009 IP
  6. Tom12361

    Tom12361 Active Member

    Messages:
    442
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    58
    #6
    So firstly .php files are executed and only after that html are executed too?
     
    Tom12361, Aug 14, 2009 IP
  7. kblessinggr

    kblessinggr Peon

    Messages:
    539
    Likes Received:
    13
    Best Answers:
    0
    Trophy Points:
    0
    #7
    No it goes like this.

    User requests a page from webserver.
    Webserver finds the php file thats been requested
    Webserver notices it has a .php extension
    php file gets fed thru a PHP interpretor
    Webserver takes final calculated output from the interpretor (usually html output) and sends it back to the User.

    So everything in <? ... ?> was already executed and processed long before the output was being sent back to the browser.
     
    kblessinggr, Aug 14, 2009 IP
  8. Gray Fox

    Gray Fox Well-Known Member

    Messages:
    196
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    130
    #8
    I think there was a small misunderstanding, first index.php finishes parsing HTML and displays it, and after that user's browser requests all other files included in that HTML (images, javascripts, stylesheets etc). In this case, captcha.php is requested as an image and run AFTER index.php has finished its job and displayed HTML.
     
    Gray Fox, Aug 14, 2009 IP
  9. premiumscripts

    premiumscripts Peon

    Messages:
    1,062
    Likes Received:
    48
    Best Answers:
    0
    Trophy Points:
    0
    #9
    Yep, use recaptcha. It will undoubtedly work better than anything you build yourself. They have plugins available for a multitude of languages including php: http://recaptcha.net/plugins/php/
     
    premiumscripts, Aug 15, 2009 IP