2
votes

I have some code generating CAPTCHA as an image file, I request the CAPTCHA as follows in myForm.php :

...
    <div class="form-group img">
        <img src="../path/to/my/captcha.php?form=myForm">
    </div>
...

the captcha.php code is as follows :

<?php
error_reporting(E_ALL & ~E_NOTICE);
session_start();
include('captcha-gen.php');
$captcha = new captcha();
$_SESSION[$_GET['form']]['captcha_keystring'] = $captcha->getKeyString();

The session only updates the first time with the CAPTCHA code in the generated image. If I refresh the page, a new CAPTCHA image is generated but the $_SESSION[$_GET['form']] never gets updated again.

This same CAPTCHA works perfectly on localhost but when I published the site I got into this problem, please advice what could be going wrong.

Update

I have done a lot of investigation on this, the captcha seems to change in the session in two cases:

  1. The first time it has loaded
  2. If any code changes in the file captcha.php

I think this is a caching issue although I tried all sorts of clearing the cache by PHP header or by html <meta http-equiv.... But it never worked...

Here are the full files list :

captcha-config.php

<?php
$use_symbols = "012345679"; 
$use_symbols_len=strlen($use_symbols);

$amplitude_min=10;
$amplitude_max=20; 

$font_width=25; 

$rand_bsimb_min=3; 
$rand_bsimb_max=5; 

$margin_left=10;
$margin_top=50; 

$font_size=40;

$jpeg_quality = 90; 
$back_count = 1; 
$length = 6; 

?>

captcha-gen.php

<?php
require_once(dirname(__FILE__).'/captcha-config.php');

class captcha
{
    function captcha()
    {
        require(dirname(__FILE__).'/captcha-config.php');

        $this->keystring='';

        for($i=0;$i<$length;$i++)
            $this->keystring.=$use_symbols{mt_rand(0,$use_symbols_len-1)};

        //echo $this->keystring . '<br />';

        $im=imagecreatefromgif(dirname(__FILE__)."/back.gif");
        $width = imagesx($im);
        $height = imagesy($im);
        $rc=mt_rand(120,140);
        $font_color = imagecolorresolve($im, $rc, $rc,$rc);
        $px =$margin_left;


        For($i=0;$i<$length;$i++)
        {
            imagettftext($im,$font_size,0,$px, $margin_top,$font_color,dirname(__FILE__)."/CARTOON8.TTF",$this->keystring[$i]);
            $px+=$font_width+mt_rand($rand_bsimb_min,$rand_bsimb_max); 
        }

        $h_y=mt_rand(0,$height);
        $h_y1=mt_rand(0,$height);
        imageline($im,mt_rand(0,20),$h_y,mt_rand($width-20,$width),$h_y1,$font_color);
        imageline($im,mt_rand(0,20),$h_y,mt_rand($width-20,$width),$h_y1,$font_color);
        $h_y=mt_rand(0,$height);
        $h_y1=mt_rand(0,$height);
        imageline($im,mt_rand(0,20),$h_y,mt_rand($width-20,$width),$h_y1,$font_color);
        imageline($im,mt_rand(0,20),$h_y,mt_rand($width-20,$width),$h_y1,$font_color);
        image_make_pomexi($im,50,80);

        $rand=mt_rand(0,1);
        if ($rand)$rand=-1; else $rand=1;
        wave_region($im,0,0,$width,$height,$rand*mt_rand($amplitude_min,$amplitude_max),mt_rand(30,40));
        header('Expires: Sat, 17 May 2008 05:00:00 GMT'); 
        header('Cache-Control: no-store, no-cache, must-revalidate'); 
        header('Cache-Control: post-check=0, pre-check=0', FALSE); 
        header('Pragma: no-cache');
        if(function_exists("imagejpeg"))
        {
            header("Content-Type: image/jpeg");
            imagejpeg($im, null, $jpeg_quality);
        }else if(function_exists("imagegif"))
        {
            header("Content-Type: image/gif");
            imagegif($im);
        }else if(function_exists("imagepng"))
        {
            header("Content-Type: image/x-png");
            imagepng($im);
        }
    }


    function getKeyString(){
        return $this->keystring;
    }
}

function wave_region($img, $x, $y, $width, $height,$amplitude = 4.5,$period = 30)
{
    $mult = 2;
    $img2 = imagecreatetruecolor($width * $mult, $height * $mult);

    imagecopyresampled ($img2,$img,0,0,$x,$y,$width * $mult,$height * $mult,$width, $height);

    for ($i = 0;$i < ($width * $mult);$i += 2)
       imagecopy($img2,$img2,$x + $i - 2,$y + sin($i / $period) * $amplitude,$x + $i,$y, 2,($height * $mult));

    imagecopyresampled($img,$img2,$x,$y,0,0,$width, $height,$width * $mult,$height * $mult);
    imagedestroy($img2);
 }

function image_make_pomexi(&$im,$size,$colch)
{
   $max_x=imagesx($im);
   $max_y=imagesy($im);
   for ($i=0;$i<=$colch;$i++)
   {
        $size=mt_rand(10,$size);
        $px1=mt_rand(0,$max_x);
        $py1=mt_rand(0,$max_y);
        $col=imagecolorresolve($im, 255, 255, 255); 
        $pk1=mt_rand(-1,1);
        $pk2=mt_rand(-1,1);
        imageline($im,$px1,$py1,$px1+$size*$pk1,$py1+$size*$pk2,$col);
    }   
}

Please advice, this blew up my mind...

1
Hm..., first time I see this type of syntax $_SESSION[$_GET['form']] - Funk Forty Niner
I have multiple forms in the website all using the same captcha code, so I index each form in the session with its own value from the query string.. - KAD
Plus, if you've anything in include('captcha-gen.php'); that would cause a headers sent notice, then you should place your session start over that. Check for errors php.net/manual/en/function.error-reporting.php - Funk Forty Niner
@Fred-ii- I have put the session_start() before and removed notice from error reporting but still getting the same result.. Please check the edit. How could it update the first time and not update again!! - KAD

1 Answers

1
votes

If the session size is big, it could be allocating the whole memory limit allowed by the shared hosting, and is preventing it from being updated.

Since this is working on localhost where the memory is open up to the size of your hardware so you won't be facing such issue.

Check the session data and try to reduce the amount of data in the session.