Help with fwrite()

He has: 296 posts

Joined: May 2002

I'm helping my friend with a PHP script that reads a file, checks to see how many times the string has been shown, if it hasn't been shown to many times then we show it and incremnet the times shown... errr, it's supposed to increment it. What I have are two files: index.php and ratios.dat. The file index.php reads ratios.dat and goes through each line and creates a ratio (numshown/100). When it finds the line of the string to show then it checks it against all other ratios. If it checks out OK then the string is shown. All this is supposed to work, but it doesn't.

Part of index.php that does the work: (Commented line is above the line that doesn't work)

<?php
function SetRatio() {
  global
$random,$filename;
  if (
is_writable($filename)) {
    if (!
$fp = fopen($filename, 'r+')) {
      print \
"Cannot open file ($filename)\";
      exit;
    }
   
$id = '1';
    while (
$ratios = fscanf ($fp, \"%s\n\")) {
      list (
$shown) = $ratios;
      if (
$id == $random) {
       
$sid = $id;
       
$shown = $shown+1;
        //This line ain't workin' ><
        fwrite(
$fp, $shown);
      }
     
$id++;
    }
    fclose(
$fp);
  } else {
    print \"The file
$filename is not writable\";
  }
}

function CheckRatios() {
  global
$random,$maxshown,$numquotes,$filename;
  if (!
$fp = fopen($filename, 'r')) {
    print \"Cannot open file (
$filename)\";
    exit;
  }
 
$id = '1';
  while (
$ratios = fscanf ($fp, \"%s\n\")) {
    list (
$shown) = $ratios;
   
$ratio[$id] = $shown/$maxshown;
   
$id++;
  }
 
$i='1';
  while (
$i <= $numquotes) {
    if (
$ratio[$random] != $ratio[$i]) {
      die(\"Ratios are off. I'll do more stuff later :p\");
    }
   
$i++;
  }
  fclose(
$fp);
}
?>

Can anyone help me?

Stupid BBCode smilies ><

[James Logsdon]

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

your opening the file as read only....
if (!$fp = fopen($filename, 'r+')) {

try this:
if (!$fp = fopen($filename, 'rw+')) {

He has: 296 posts

Joined: May 2002

Still doesn't work >< The script is located here

Suzanne's picture

She has: 5,507 posts

Joined: Feb 2000

Can you save that as index.phps so we can see the php source?

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

try this:

<?php
function SetRatio() {
  global
$random,$filename;
  if (
is_writable($filename)) {
    if (!
$fp = fopen($filename, 'rw+')) {
      print \
"Cannot open file ($filename)\";
      exit;
    }
    else {
     
$id = '1';
      while (
$ratios = fscanf ($fp, \"%s\n\")) {
        list (
$shown) = $ratios;
        if (
$id == $random) {
         
$sid = $id;
         
$shown = $shown+1;
          if (!fwrite(
$fp, $shown)) {
            print \"Error writting to (
$filename)\";
            exit;
          }
        }
        
$id++;
      }
      fclose(
$fp);
    }
  }
  else {
    print \"The file
$filename is not writable\";
  }
}
?>
I went to the script, and kept getting random quotes. No errors were printed, but the dat file didn't update. This should help find where it's failing... hopefully.

I'm glad you like sourceviewer. I haven't gotten feedback from anyone. I see your using vesion 1.0.1. There is a version 1.1.0 available. Changes include:
+ made complient with W3C's HTML 4.01 Transitional standards
+ made compatable with PHP <4.2.0 and >=4.2.0
+ added error_reporting()
+ added links to included files

Mark Hensler
If there is no answer on Google, then there is no question.

He has: 296 posts

Joined: May 2002

Awesome, I'll probably start using 1.1.0 then Sticking out tongue.

I'll try that in a few minutes, gotta do dishes first ><

>< Server's down.... back up now Sticking out tongue

Mark, I tried your change. It still doesn't work and now ever few times I reload the page I get the error "Cannot open file (ratios.dat)"

[James Logsdon]

He has: 296 posts

Joined: May 2002

Mark, as I posted above, your changes didn't work Sad

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

Oops, sorry. I guess I missed this thread.

I'm wondering if it's having problems writting to the same file handle it's reading from. Try this:

<?php
function SetRatio() {
  global
$random,$filename;
  if (
is_writable($filename)) {
   
$fp1 = fopen($filename, 'r+');
   
$fp2 = fopen($filename, 'w+');
    if (!
$fp1 || !$fp2) {
      print \
"Cannot open file ($filename)\";
      exit;
    }
    else {
     
      for (
$id=1; $id<=$random; $id++) {
        if (
$ratios = fscanf($fp1, \"%s\n\")) {
          list(
$shown) = $ratios;
        }
        else {
         
$shown = 0;
        }
       
        if (
$id == $random) {
         
$sid = $id;
         
$shown = $shown+1;
          if (!fwrite(
$fp2, $shown)) {
            print \"Error writting to (
$filename) on line ($id)<br>\";
            exit;
          }
        }
        else {
          if (!fwrite(
$fp2, $shown)) {
            print \"Error writting to (
$filename) on line ($id)<br>\";
            exit;
          }
        }
      }
     
      // copy the rest of file 1 to file 2
      while (
$ratios = fscanf($fp1, \"%s\n\")) {
        list(
$shown) = $ratios;
        if (!fwrite(
$fp2, $shown)) {
          print \"Error writting to (
$filename) on line ($id)<br>\";
          exit;
        }
       
$id++;
      }
     
      fclose(
$fp1);
      fclose(
$fp2);
    }
  }
  else {
    print \"The file
$filename is not writable\";
  }
}
?>

Mark Hensler
If there is no answer on Google, then there is no question.

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

Your ratios file isn't that large, so you could try sucking it into an array right off the bat. Then just increment the one number, and write the whole array to the file again.

<?php
function SetRatio() {
  global
$random,$filename;
  if (
is_writable($filename)) {
   
$dat_file = file($filename);
   
   
$fp = fopen($filename, 'w');
    if (!
$fp) {
      print \
"Cannot open file ($filename)\";
      exit;
    }
    else {
     
     
$max = (count($file)>$random) ? count($file) : $random;
     
      for (
$id=1; $id<=$max; $id++) {
        if (
$id<=count($file)) {
         
$shown = $file[$id];
        }
        else {
         
$shown = 0;
        }
       
        if (
$id == $random) {
         
$sid = $id;
         
$shown = $shown+1;
        }
       
        if (!fwrite(
$fp, $shown)) {
          print \"Error writting to (
$filename) on line ($id)<br>\";
          exit;
        }
      }
     
      fclose(
$fp);
    }
  }
  else {
    print \"The file
$filename is not writable\";
  }
}
?>

Mark Hensler
If there is no answer on Google, then there is no question.

He has: 296 posts

Joined: May 2002

I tried both of them and it didn't work. Well, it did. But it just made one line in the file and it was as long as the Random Int (1-15). So if the rand was 5 it would put 00001 in the file.

[James Logsdon]

He has: 296 posts

Joined: May 2002

I was looking at your code. Where'd you get $file from? It's not anywhere in your code or mine. Is it supposed to be $fp?

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

I'm sorry, that should be $dat_file.

and to fix the formatting problem, change fwrite() to:
fwrite($fp, "$shown\n")

He has: 296 posts

Joined: May 2002

And the resulting outcome: http://www.eracreations.com/sourceviewer_101.php?file=/members/necrotic/ratios.dat ... wow

EDIT: I see what it's doing. It's added a new line for every time the script is run. So if I run it ten times, there will be 10 lines between each number.

[James Logsdon]

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

hmm, take out that \n then

He has: 296 posts

Joined: May 2002

Quote: Originally posted by necrotic
I tried both of them and it didn't work. Well, it did. But it just made one line in the file and it was as long as the Random Int (1-15). So if the rand was 5 it would put 00001 in the file.

I would, but then that would happen. I might just have to use MySQL instead =\ I really wanted to use flat files, and it's not working ><

[James Logsdon]

Mark Hensler's picture

He has: 4,048 posts

Joined: Aug 2000

I don't see why it was printing all those \n's.

mySQL is the ideal solution. It's much faster than flat files.

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.