Problem with script counter.php

below is the code i am using, i think i am going wrong at the png bit because i read somewhere the code does not need changing but i think it does.

`

<?php session_start(); $debug = true; // Change this to false when you want to stop the extra echos $counter_name = "counter.txt"; // Check if a text file exists. If not create one and initialize it to zero. if (!file_exists($counter_name)) { $f = fopen($counter_name, "w"); fwrite($f,"0"); fclose($f); } // Read the current value of our counter file $f = fopen($counter_name,"r"); $counterVal = fread($f, filesize($counter_name)); fclose($f); // Has visitor been counted in this session? // If not, increase counter value by one if(!isset($_SESSION['hasVisited'])){ $_SESSION['hasVisited']="yes"; $counterVal++; $f = fopen($counter_name, "w"); fwrite($f, $counterVal); fclose($f); } $counterVal = str_pad($counterVal, 5, "0", STR_PAD_LEFT); $chars = preg_split('//', $counterVal); $im = imagecreatefrompng("canvas2.png"); $src1 = imagecreatefrompng("$chars[0].png"); $src2 = imagecreatefrompng("$chars[1].png"); $src3 = imagecreatefrompng("$chars[2].png"); $src4 = imagecreatefrompng("$chars[3].png"); $src5 = imagecreatefrompng("$chars[4].png"); imagecopymerge($im, $src1, 0, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src2, 60, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src3, 120, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src4, 180, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src5, 240, 0, 0, 0, 56, 75, 100); // Output and free from memory header('Content-Type: image/png'); echo imagepng($im); imagedestroy($im); ?>

`
i am sure it should say:-
$chars[0] = “0”;
$src1 = imagecreatefrompng(“0.png”); and so on, or have i got this wrong

I think you have got it wrong.

$chars holds the single digits from a five digit number. If you force $chars[0] to be’0’ then when the number goes over 09999 it would reset to 00000 instead of continuing to 10000.

1 Like

You’ve still got this code slightly wrong:

echo imagepng($im);

I believe it needs to read just

imagepng($im);
1 Like

yes i read that somewhere so i removed the echo,
unfortuatly its still not working i can’t get it to show any images, just says “hit counter” on my webpage. does anyone have this working on a live webpage.
below is the code i am using:-
`

<?php session_start(); $debug = true; // Change this to false when you want to stop the extra echos $counter_name = "counter.txt"; // Check if a text file exists. If not create one and initialize it to zero. if (!file_exists($counter_name)) { $f = fopen($counter_name, "w"); fwrite($f,"0"); fclose($f); } // Read the current value of our counter file $f = fopen($counter_name,"r"); $counterVal = fread($f, filesize($counter_name)); fclose($f); // Has visitor been counted in this session? // If not, increase counter value by one if(!isset($_SESSION['hasVisited'])){ $_SESSION['hasVisited']="yes"; $counterVal++; $f = fopen($counter_name, "w"); fwrite($f, $counterVal); fclose($f); } $counterVal = str_pad($counterVal, 5, "0", STR_PAD_LEFT); $chars = preg_split('//', $counterVal); $im = imagecreatefrompng("canvas2.png"); $src1 = imagecreatefrompng("$chars[0].png"); $src2 = imagecreatefrompng("$chars[1].png"); $src3 = imagecreatefrompng("$chars[2].png"); $src4 = imagecreatefrompng("$chars[3].png"); $src5 = imagecreatefrompng("$chars[4].png"); imagecopymerge($im, $src1, 0, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src2, 60, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src3, 120, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src4, 180, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src5, 240, 0, 0, 0, 56, 75, 100); // Output and free from memory header('Content-Type: image/png'); imagepng($im); imagedestroy($im); ?>

`
still not understanding if my counter went to 88 how does the script know to use the image file 8.png if its not in the code??

I can’t obviously see anything wrong with your code. It looks exactly as in the tutorial. You have got your canvas.png and digit image files in the same directory as your script, haven’t you?

I tried to explain this but didn’t do very well, @droopsnoot did a better job in post #40

thanks gandalf, yes i have canvas and 0.png to 9.png in the same folder, if the code is ok thne its got to be something to do with the images i have resize them and the canvas is transparent, any ideas ?? i did change the code to canvas2.png because i had 2 canvas files.

Droopsnoot say i should have this in my code:-
$src4 = imagecreatefrompng("3.png");

but mine say:-
$src4 = imagecreatefrompng("$chars[3].png");

thats the bit i am not clear on

You have just indicated something that IS wrong with your code which I failed to spot. You have, I think, got the following:

$src1 = imagecreatefrompng("$chars[0].png");
$src2 = imagecreatefrompng("$chars[1].png");
$src3 = imagecreatefrompng("$chars[2].png");
$src4 = imagecreatefrompng("$chars[3].png");
$src5 = imagecreatefrompng("$chars[4].png");

but the code (which works!) in the tutorial is

$src1 = imagecreatefrompng("$chars[1].png"); 
$src2 = imagecreatefrompng("$chars[2].png"); 
$src3 = imagecreatefrompng("$chars[3].png"); 
$src4 = imagecreatefrompng("$chars[4].png"); 
$src5 = imagecreatefrompng("$chars[5].png"); 

I’m not sure why you changed the original, but using the exact code from the tutorial should do the job.

ok i have changed it, i thought i needed to have the zero first, any its still not working, do you think its a file permission problem

I’ve been playing with this for a little while

First, the $chars[] array key “number” is not the value of that array key.
(OK, that even confuses me and I just wrote it :wink:)

In other words, as an example, the “[1]” does not mean it’s the 1.png it means it’s the second member of the array (most likely one of the pad added zeroes at this point).

As for [0] it is true that the array starts with zero.

However, the preg_split returns an empty string - ‘’ - as the first and last array members.

If you are going to keep the preg_split, you will want to skip over the empty string and start off with [1].

My personal preference for something trivial is to use str_split, but that would require changing some code as no empty strings get returned


$counterVal = str_pad($counterVal, 5, "0", STR_PAD_LEFT);
//$chars = preg_split('//', $counterVal);
$chars = str_split($counterVal);
$im = imagecreatefrompng("canvas.png");  // 296 x 75
//$src1 = imagecreatefrompng($chars[1] . ".png");  // 56 x 75
//$src2 = imagecreatefrompng($chars[2] . ".png");
//$src3 = imagecreatefrompng($chars[3] . ".png");
//$src4 = imagecreatefrompng($chars[4] . ".png");
//$src5 = imagecreatefrompng($chars[5] . ".png");
$src1 = imagecreatefrompng($chars[0] . ".png");  // 56 x 75
$src2 = imagecreatefrompng($chars[1] . ".png");
$src3 = imagecreatefrompng($chars[2] . ".png");
$src4 = imagecreatefrompng($chars[3] . ".png");
$src5 = imagecreatefrompng($chars[4] . ".png");

*I also changed the variable - string bit. PHP parses variables inside double quotes, it’s just that I don’t like doing it that way. No offense intended @James_Hibbard

Given the problem you had when you created counter.txt rather than allowed the script to create it, perhaps the problem is the file ownership. If you check the ownership of counter.txt and change the ownership of the image files to the same…

No, I was saying that’s effectively what you have. Where your code has $chars[3] in that line, if the value of $chars[3] is 3, then it will be referencing 3.png, and so on. PHP will substitute the value of variable $chars[3] into the string.

1 Like

OK, as it’s getting frustrating, I created some images and ran the original code on my WAMP server here. Out of the box, it works. I don’t quite understand why, but it does. For example, I don’t get why the preg_split line returns this, but then I don’t understand regular expressions to start with.

array (size=7)  { this is $chars[] }
  0 => string '' (length=0)
  1 => string '0' (length=1)
  2 => string '0' (length=1)
  3 => string '0' (length=1)
  4 => string '0' (length=1)
  5 => string '1' (length=1)
  6 => string '' (length=0)

string '00001' (length=5)  {  this is $counterVal }

when I var_dump($chars) followed by $counterVal. Hence the offsets for the array in the original code are correct, starting at 1 and going to 5, not base zero as I said . The echo before imagpng also doesn’t seem to cause any trouble - it works exactly the same whether I leave it in or remove it - I assume imagepng() outputs the image contents, then php follows it with true or false, which is ignored for some reason by the browser.

Backing up to your first post, you say " i have saved the following files on my web server in /srv/http" and then list the png files. Can you move them all to the same directory your php is in? That’s where they are for me - if you have them somewhere else, I think you’ll need to modify the lines to reference them, but I would expect you’d be getting error messages. Or are you still getting error messages? I think you’ll need to call /counter.php directly to see them.

(I’ve had a quick read down the thread and can’t see a point where you say you’ve copied them there, apologise if you already have and this is yet another confusion).

Yes, that’s the regex // it “matches” the beginning and the ending non-character.
Definitely not a commonly seen pattern, but that’s what it does.

The PHP docs show an example that uses a Flag to deal with it
http://php.net/manual/en/function.preg-split.php
Example #2 Splitting a string into component characters

<?php
$str = 'string';
$chars = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
print_r($chars);
?>

Try changing it to /./ or /./g

But it works fine as it is!

I was suggesting it as a comparison to the original for seeing how the regular expression works.

I tried looking for a regex tester that would allow you to test with nothing between the // but couldn’t find one - also you can’t use an empty expression in all languages (perhaps a reason why it isn’t commonly used).

That matches any character instead of any non-character

$chars = preg_split('/./', $counterVal);
var_dump($chars);
exit;

array(6) { [0]=> string(0) “” [1]=> string(0) “” [2]=> string(0) “” [3]=> string(0) “” [4]=> string(0) “” [5]=> string(0) “” }

This more closely demonstrates

$chars = preg_split('/[^\d]?/', $counterVal);

or

$chars = preg_split('/[\D]?/', $counterVal);

But also returns the beginning and ending “empties”

I tried different regex patterns to not include the “empties” but have failed so far.

array_pop($chars);
array_shift($chars);

works, But I think if one is to use preg_split probably easier to just skip the [0] and start with [1]

And as I posted previous, for this use I prefer str_split anyway. I don’t really see a need to use regex here even though the code does work as it is.

Sorry if i am i bit slow but i now understand ($chars); with reference to calling png files. thank you all for that.

droopsnoot
My file are all in the same directory /srv/http

Gandalf,
I did as you asked changed the ownnership of all the files from root to http. i noticed when i deleted counter.txt the system re-created it as:-
-rw-r–r-- 1 http http counter.txt
so i have changed the ownership to http.
command used:- chown http counter.php
and file permission to:- chmod 766 counter.php
one example is :-
-rwxrwxrwx 1 http root 2009 Feb 11 00:24 counter.php

I even changed the code to the examples given by Mittineague and felgall

BUT STILL NO LUCK!! its driving mad the only good thing is i understand the png bit. below is the current code i am using i have left the debug in becuase if i take it out and just run the file http://ipadress/counter.php i just get a blank screen no number count:-
`

<?php session_start(); $debug = true; // Change this to false when you want to stop the extra echos $counter_name = "counter.txt"; // Check if a text file exists. If not create one and initialize it to zero. if (!file_exists($counter_name)) { if ($debug) echo "Counter file did not exist"; // ** DEBUG $f = fopen($counter_name, "w"); fwrite($f,"0"); fclose($f); } // Read the current value of our counter file $f = fopen($counter_name,"r"); $counterVal = fread($f, filesize($counter_name)); fclose($f); if ($debug) echo "Counter value is " . $counterVal; // ** DEBUG // Has visitor been counted in this session? // If not, increase counter value by one if(!isset($_SESSION['hasVisited'])){ $_SESSION['hasVisited']="yes"; $counterVal++; $f = fopen($counter_name, "w"); fwrite($f, $counterVal); fclose($f); if ($debug) echo "Incremented counter"; // ** DEBUG } $counterVal = str_pad($counterVal, 5, "0", STR_PAD_LEFT); $chars = str_split($counterVal); $im = imagecreatefrompng("canvas2.png"); // 300 x 75 $src1 = imagecreatefrompng($chars[0] . ".png"); // 56 x 75 $src2 = imagecreatefrompng($chars[1] . ".png"); $src3 = imagecreatefrompng($chars[2] . ".png"); $src4 = imagecreatefrompng($chars[3] . ".png"); $src5 = imagecreatefrompng($chars[4] . ".png"); imagecopymerge($im, $src1, 0, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src2, 60, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src3, 120, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src4, 180, 0, 0, 0, 56, 75, 100); imagecopymerge($im, $src5, 240, 0, 0, 0, 56, 75, 100); // Output and free from memory header('Content-Type: image/png'); imagepng($im); imagedestroy($im); ?>

`

For testing, you should put
exit;
inside the
if ($debug) {
conditionals after the echo

The script wants to send header('Content-Type: image/png');
BUT if the script does an echo it will send text headers first and the script will choke.

....
if ($debug) {
  echo "Counter file did not exist";
  exit;
} // ** DEBUG
....
if ($debug) { 
  echo "Counter value is " . $counterVal;
  exit;
} // ** DEBUG
....
if ($debug) {
  echo "Incremented counter";
  exit;
} // ** DEBUG 
....

If you make it past the first comment out the

// echo
// ext

and so on until it makes it all the way through