PDA

View Full Version : fclose() error and can't figure it out!



BLiZZaRD
04-02-2006, 07:36 PM
Hello everyone... hopefully this will be quick:

I have a flash game that writes the submitted final score and log in name to the highscores list through php (no SQL here)

Everything is set up, everything works, and get this: on another site the scores work perfectly!

Now when I take all the files off the test site and place them on the final resting place site the highscores wont work (and yes I changed ALL instances of global.domain= LOL)

I have traced the error and made a report, and I get this:

PHP Warning: fclose(): supplied argument is not a valid stream resource in /my/domain/and/path/to/scores.php on line 9

line 9 of the scores.php looks like this:

fclose ($file);


with the whole lines upto there as this:

<?php

$winscore = (int)$winscore;

// Create a Blank File if it doesn't already exist
if (!file_exists($filename))
{
$file=fopen($filename, "w");
fclose ($file);
}


So, with this error pointing to the php, I am guessing it is there? Anyone know how to get by this?

Thanks!
________

Twey
04-02-2006, 08:07 PM
The only possible problem here is if $filename can't be written. Check that the user your scripts run as has write permission to the directory in which you're attempting to create this file.

BLiZZaRD
04-03-2006, 06:14 PM
ALL files in this directory have either a 755 or a 777 CHMOD. Is this what you mean? Or something else?

Twey
04-03-2006, 06:27 PM
What about the directory itself?

BLiZZaRD
04-03-2006, 06:30 PM
The directory itself is 777 as is the sub-directory...

now you see my problem? LOL

Twey
04-03-2006, 06:45 PM
Are you sure $filename contains what you expect it to contain? Try echoing it before you call fopen().

BLiZZaRD
04-03-2006, 06:51 PM
I have been fighting with this for about 2 months now. I am not sure of anything anymore.

$filename makes a file called highscores.sco if it doesn't exist yet. Which it doesn't. The first time someone played the game and submits a highscore, it should create the highscores.sco file and write the name and score to it.

then the page is displayed. Everything works except the name and score doesn't get written and the highscores.sco file doesn't get created.

I just don't understand it.

*****************

<edit> I just did a double check, the folders are only 755. if I try to CHMOD them to 777 I get 500 errors when trying to access the html inside them... could this be the problem?

Alos I did the echo and it gave the same error the error log did about line 9 and the fclose() I don't know what an fclose() does exactly, I am guessing it closes the file after the writing has been done...

</edit>

Twey
04-03-2006, 07:24 PM
Alos I did the echo and it gave the same error the error log did about line 9 and the fclose() I don't know what an fclose() does exactly, I am guessing it closes the file after the writing has been done...You did echo($filename); before the fopen() call? Can you show me the output? You're right about the function of fclose().
If you touch and chmod 777 highscores.sco before running the script, does it work?

BLiZZaRD
04-03-2006, 08:06 PM
no, maybe I didn't do that. I am so confused right now my brain hurts.

here is the entire scores.php:



<?php

$winscore = (int)$winscore;

// Create a Blank File if it doesn't already exist
if (!file_exists($filename))
{
$file=fopen($filename, "w");
fclose ($file);
}

// Read the file in
$oscores = file ($filename);
$numreadin = count($oscores);

// Break out the data into a new 2-d array called $tscores
for ($i = 0; $i < $numreadin; $i++)
{
$g = unserialize($oscores[$i]);
$tscores[$i][0] = $g[0];
$tscores[$i][1] = $g[1];
}

// Fill in any missing data with none/0
for ($i = $numreadin; $i < $scoresize; $i++)
{
$tscores[$i][0] = 0;
$tscores[$i][1] = "";
}

// Process the actions

// Insert a score/name
if ($action == "INSERT")
{

// Add name to end of list, and sort
$tscores[$scoresize + 1][0] = $winscore;
$tscores[$scoresize + 1][1] = $winname;
rsort ($tscores);

$file=fopen($filename, "w");

// Write them out
for ($i = 0; $i < $scoresize; $i++)
{
$st = serialize($tscores[$i]) . "\n";
fputs($file, $st);
}

fclose($file);
}

// Clear the list
if ($action == "CLEAR")
{

$k[0] = 0;
$k[1] = "no-one";
$ser = serialize($k);

$file=fopen($filename, "w");

for ($i = 0; $i < $scoresize; $i++)
{
$st = $ser . "\n";
fputs($file, $st);
}

fclose($file);
}

// Process the OUTPUT options
if ($viewtype == "HTML")
{
// HTML PAGE CREATED HERE
?>



<table cellpadding=2 cellspacing=2 border=0 width="330">
<tr align=center>
<th bgcolor="#663300" width="80"><font color="#ffff00" face="Arial, Helvetica, sans-serif" size="1">Rank</font></th>
<th bgcolor="#663300" width="126"><font color="#FFFF00" face="Arial, Helvetica, sans-serif" size="1">Name</font></th>
<th bgcolor="#663300" width="104"><font color="#FFFF00" face="Arial, Helvetica, sans-serif" size="1">Score</font></th>
</tr>
<?

for ($i = 0; $i < $scoresize; $i++)
{
echo ("<tr bgcolor='#669933' align='center'><td><font size='1' face='Arial, Helvetica, sans-serif'>");
echo ($i + 1);
echo ("</font></td><td><font size='1' face='Arial, Helvetica, sans-serif'>");
echo ($tscores[$i][1]);
echo ("</font></td><td><font size='1' face='Arial, Helvetica, sans-serif'>");
echo ($tscores[$i][0]);
echo ("</font></td></tr>");
}

?>
</table>
<?

}

// FLASH DATA CREATED HERE
if ($viewtype == "FLASH")
{
for ($i = 0; $i < $scoresize; $i++)
{
echo ("name" . $i . "=");
echo ($tscores[$i][1]);
echo ("&score" . $i . "=");
echo ($tscores[$i][0]);
echo ("&");
}
}

?>


if I browse to it I get the WARNING: fclose().... thing

If I try to add the echo($filename); at the top I get a parse error.

the thing works like this: (for clarification)

I have root folder(755)>>game folder(755)>>scores folder(755)>>highscores.sco(777)

the html(755) and game.swf(755) are in game folder.
also scores.php (the above code) is in game folder and also (777).

the link in the swf tells scores.php to start doing its thing, and tells it that the global domain is my domain and the .sco is at scores/highscore.sco

All of that is set up exactly the same, and works on the other site. when I copy the files over from the test site to my permanent site everything works but the scores. They stay blank.

Thanks for helping me out (again) Twey

Twey
04-03-2006, 08:47 PM
All of that is set up exactly the same, and works on the other site.Right. Sounds like the scores folder isn't owned by the user your scripts run as. Save this PHP script as whoami.php:
<?php echo(`whoami`); ?>then
$ chown -R `php whoami.php` scores

BLiZZaRD
04-03-2006, 08:58 PM
okay I made the whoami.php and it said my usr name

I am not sure what you mean for me to do with this:



$ chown -R `php whoami.php` scores


:confused:

Twey
04-03-2006, 09:21 PM
It's a shell command. Run it as the user that currently owns the files. It will change the ownership of scores and all files under it to the user output by whoami.php.

BLiZZaRD
04-03-2006, 09:30 PM
using putty I did that command..

it responded with:

chown 'php whoami.php' :invalid user


:confused: :cry: :whine: :cry:

Twey
04-03-2006, 09:43 PM
Those are backticks (`) not apostrophes ('). I only used them for simplicity; you could just as well substitute the output of the whoami.php file for `php whoami.php`.

BLiZZaRD
05-09-2006, 08:09 PM
I am back after a long delay of this stupid thing called real life...

I have verified with the host, and the folders are most definetly mine. It is something in this php code I am sure... I just don't know what.

here is the complete script:



<?php

$winscore = (int)$winscore;

// Create a Blank File if it doesn't already exist
if (!file_exists($filename))
{
$file=fopen($filename, "w");
fclose ($file);
}

// Read the file in
$oscores = file ($filename);
$numreadin = count($oscores);

// Break out the data into a new 2-d array called $tscores
for ($i = 0; $i < $numreadin; $i++)
{
$g = unserialize($oscores[$i]);
$tscores[$i][0] = $g[0];
$tscores[$i][1] = $g[1];
}

// Fill in any missing data with none/0
for ($i = $numreadin; $i < $scoresize; $i++)
{
$tscores[$i][0] = 0;
$tscores[$i][1] = "";
}

// Process the actions

// Insert a score/name
if ($action == "INSERT")
{

// Add name to end of list, and sort
$tscores[$scoresize + 1][0] = $winscore;
$tscores[$scoresize + 1][1] = $winname;
rsort ($tscores);

$file=fopen($filename, "w");

// Write them out
for ($i = 0; $i < $scoresize; $i++)
{
$st = serialize($tscores[$i]) . "\n";
fputs($file, $st);
}

fclose($file);
}

// Clear the list
if ($action == "CLEAR")
{

$k[0] = 0;
$k[1] = "no-one";
$ser = serialize($k);

$file=fopen($filename, "w");

for ($i = 0; $i < $scoresize; $i++)
{
$st = $ser . "\n";
fputs($file, $st);
}

fclose($file);
}

// Process the OUTPUT options
if ($viewtype == "HTML")
{
// HTML PAGE CREATED HERE
?>



<table cellpadding=2 cellspacing=2 border=0 width="330">
<tr align=center>
<th bgcolor="#663300" width="80"><font color="#ffff00" face="Arial, Helvetica, sans-serif" size="1">Rank</font></th>
<th bgcolor="#663300" width="126"><font color="#FFFF00" face="Arial, Helvetica, sans-serif" size="1">Name</font></th>
<th bgcolor="#663300" width="104"><font color="#FFFF00" face="Arial, Helvetica, sans-serif" size="1">Score</font></th>
</tr>
<?

for ($i = 0; $i < $scoresize; $i++)
{
echo ("<tr bgcolor='#669933' align='center'><td><font size='1' face='Arial, Helvetica, sans-serif'>");
echo ($i + 1);
echo ("</font></td><td><font size='1' face='Arial, Helvetica, sans-serif'>");
echo ($tscores[$i][1]);
echo ("</font></td><td><font size='1' face='Arial, Helvetica, sans-serif'>");
echo ($tscores[$i][0]);
echo ("</font></td></tr>");
}

?>
</table>
<?

}

// FLASH DATA CREATED HERE
if ($viewtype == "FLASH")
{
for ($i = 0; $i < $scoresize; $i++)
{
echo ("name" . $i . "=");
echo ($tscores[$i][1]);
echo ("&score" . $i . "=");
echo ($tscores[$i][0]);
echo ("&");
}
}

?>


the error I get is:



[09-May-2006 15:55:27] PHP Warning: fclose(): supplied argument is not a valid stream resource in /path/to/the/folder/scores.php on line 9


Any ideas? I am just befuddled with this whole thing.

I really do not want to have to code 6000 lines of action script again just to make an external high scores list for Flash... sigh.. anything? anyone?

Thanks guys!

Twey
05-09-2006, 08:26 PM
Is $filename defined?

BLiZZaRD
05-09-2006, 08:39 PM
in the Flash file I have it defined as this:




_global.scoreFile = "scores/highscores.sco";


This tells the flash file that scores/highscores.sco is the file name to use everytime "scoreFile" is called

In the 2 places I call the script (load and submit) I have this:



_root.filename = _global.scoreFile;



As far as in the php file itself, I guess not, if it's not in there. All I do know about this php file (I didn't write it, obv. ) is that it is to open highscores.sco, if it is already there, and create it if it does not yet exist.

Twey
05-09-2006, 08:59 PM
Well, that's probably your problem, then :) Define $filename = "scores/highscores.sco"; somewhere before calling that code.

BLiZZaRD
05-09-2006, 09:00 PM
I will give that a try and let you know!

Thanks Twey!

BLiZZaRD
05-09-2006, 09:36 PM
Well, that ALMOST worked! LOL

I added the definition and now it created the highscores.sco file like it was supposed to.

That tells me everything is reading and sending just fine.

I don't get an error log either!

The only problem now, is that it doesn't write to the sco file. It stays blank.

I CHMOD to 777 on virtually every file there, and still nothing.

I think I need another break. I can't afford to throw another computer out the window.

If you have any ideas about the writing thing though I would love to hear them.

I have a feeling I am going to have to re-do the Flash portion now though. greeeaaat... sigh.

Twey
05-09-2006, 09:46 PM
"Another?" Lol!
Use "a" instead of "w" for INSERT. Also, make sure $action (and all the other variables the script uses) is defined.

BLiZZaRD
05-11-2006, 02:02 AM
Hey! I still have a couple laptops to toss :D

Anyway, I was on my Flash help forum trying to get help with the flash side and I got this as a reply:



The PHP script relies on an old PHP setting (register_globals) to be turned on. This has been disabled by default - because of the security problems it causes - for several years.

What this setting does is make PHP automatically create global variables from the data submitted to the script (e.g. GET, POST etc...) with register globals turned off, you need to extract these values yourself from an array, $_GET for GET and, unsurprisingly $_POST for POST

With register_globals on if a variable winscore is sent to PHP using GET the variable $winscore would be created automatically. With register_globals off to create your winscore variable you might use,

$winscore = isset($_GET['winscore']) ? (int) $_GET['winscore'] : 0;

what this does is it uses isset check the $_GET array to see if it contains a value for the winscore variable. If winscore was sent to the script it uses (int) to typecast the value to an integer and stores the result in $winscore. If a winscore variable wasn't sent $winscore will default to 0.

You'd need to use a similar technique to extract all the variables sent from Flash to the script. I'd suspect the cause of the error is that $filename is undefined - due to register_globals being turned off - the undefined variable causes fopen to fail, so now your variable $file doesn't contain a valid file handle. fclose then throws the warning when it is supplied with something that it can't work with.

One thing that seems a little risky is that you're sending the filename of the scores file to the script, a devious user might spot this and start experimenting with supplying some different filenames to see what happens. It would probably be better to hard code the filename into the PHP instead of the Flash.


Does this make sense to you? I didn't write the php in the first place so I have no idea what they are really talking about... I asked for clarification over there, but nothing....

Twey
05-11-2006, 06:11 AM
Yes. For example, if you access file.php?thing=this, with register_globals turned on, the variable $thing will exist and be equal to "this". However, without it, you must go through the script explicitly defining these variables, from the $_GET and/or $_POST arrays.

BLiZZaRD
05-11-2006, 01:18 PM
Okay, that makes a little more sense.

So every time there is a variable I need to make it = something.

Okay, so here is a stupid question, how do I know what to set it equal to?

I have tried learning this PHP stuff on my own, and it is just too hard for me. I haven't given up, but I think "re-writing" a whole php page to update it, is over my head.

I will do it though! I just need a bit of guidance.

Twey
05-11-2006, 02:49 PM
Converting code for use without register_globals is easy. Go through your code, and wherever you see a variable that hasn't been defined, add a new declaration to the top of your page (example assumes that variable is named $camel):
$camel = $_GET['camel'];You should use $_POST rather than $_GET if you're using POST instead of GET, obviously.