Reading from file basics

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • deko

    #1

    Reading from file basics

    Is there a way to avoid opening and closing the file "viscount" twice in this
    code:

    <?php
    $file = 'viscount.txt';
    if ($counter = @file ($file)) {
    $line = each($counter);
    if (!$counter) {
    $counter = 1;
    } else {
    $counter = $line[value]+1;
    }
    }
    $fp = fopen ($file, "w");
    fwrite ($fp, "$counter") ;
    fclose($fp);
    $fp = fopen ($file, "r");
    $count = fgets($fp);
    echo $count;
    ?>

    I tried this:

    $fp = fopen ($file, "r+");
    fwrite ($fp, "$counter") ;
    $count = fgets($fp);
    echo $count;

    But $count returned an empty string (or would not echo).


  • Andy Hassall

    #2
    Re: Reading from file basics

    On Thu, 18 Mar 2004 22:28:42 GMT, "deko" <dje422@hotmail .com> wrote:
    [color=blue]
    >Is there a way to avoid opening and closing the file "viscount" twice in this
    >code:
    >
    ><?php
    >$file = 'viscount.txt';
    >if ($counter = @file ($file)) {
    > $line = each($counter);
    > if (!$counter) {
    > $counter = 1;
    > } else {
    > $counter = $line[value]+1;
    > }
    >}
    >$fp = fopen ($file, "w");
    >fwrite ($fp, "$counter") ;
    >fclose($fp);
    >$fp = fopen ($file, "r");
    >$count = fgets($fp);
    >echo $count;
    >?>
    >
    >I tried this:
    >
    >$fp = fopen ($file, "r+");
    >fwrite ($fp, "$counter") ;
    >$count = fgets($fp);
    >echo $count;
    >
    >But $count returned an empty string (or would not echo).[/color]

    Looks like you're assuming vicount contains a single line with a counter on
    it? You're missing file locking here - what if two people run the script at the
    same time? This is the sort of thing databases were invented for.

    Having said that, if you either put flock() calls in, or ignore the race
    condition, why are you re-opening the file and reading what you just wrote -
    just echo $counter back out?

    --
    Andy Hassall <andy@andyh.co. uk> / Space: disk usage analysis tool
    <http://www.andyh.co.uk > / <http://www.andyhsoftwa re.co.uk/space>

    Comment

    • Pedro Graca

      #3
      Re: Reading from file basics

      deko wrote:[color=blue]
      > Is there a way to avoid opening and closing the file "viscount" twice in this
      > code:[/color]

      Yes

      <?php
      // open file for reading and writing
      if (!$fh = @fopen('viscoun t', 'r+')) exit('fopen failed');

      // lock it, try ten times before giving up
      $lock_tries = 10;
      while (!flock($fh, LOCK_EX)) {
      usleep(100);
      --$lock_tries;
      if (!$lock_tries) break;
      }
      if (!$lock_tries) exit('flock (to lock) failed');

      // read data
      if (!$line = @fgets($fh)) exit('fgets failed');

      // do whatever you want with the data (... but do it fast)
      $line = (int)(trim($lin e));
      ++$line;

      // go to beginning of file
      if (@fseek($fh, 0)) exit('fseek failed');

      // clear all data in file (maybe not needed ???)
      if (!ftruncate($fh , 0)) exit('ftruncate failed');

      // write new data
      if (!fwrite($fh, $line . "\n")) exit('fwrite failed');

      // unlock file, try ten times before giving up
      $lock_tries = 10;
      while (!flock($fh, LOCK_UN)) {
      usleep(100);
      --$lock_tries;
      if (!$lock_tries) break;
      }
      if (!$lock_tries) exit('flock (to unlock) failed');

      // close file
      if (!fclose($fh)) exit('fclose failed');

      // file updated, let the user know about it
      exit('File updated, thank you for using our service.');
      ?>

      --
      USENET would be a better place if everybody read: : mail address :
      http://www.catb.org/~esr/faqs/smart-questions.html : is valid for :
      http://www.netmeister.org/news/learn2quote2.html : "text/plain" :
      http://www.expita.com/nomime.html : to 10K bytes :

      Comment

      • deko

        #4
        Re: Reading from file basics

        > Looks like you're assuming visount contains a single line with a counter on[color=blue]
        > it? You're missing file locking here - what if two people run the script at[/color]
        the[color=blue]
        > same time? This is the sort of thing databases were invented for.[/color]

        I agree, a database could be used - but this is a traffic counter, and that
        would mean a lot of overhead if I were using a database.
        [color=blue]
        > Having said that, if you either put flock() calls in, or ignore the race
        > condition, why are you re-opening the file and reading what you just wrote -
        > just echo $counter back out?[/color]

        How do I ignore the race condition? would that be better than using flock()?

        <?php
        $file = 'viscount.txt';
        if ($counter = @file ($file)) {
        $line = each($counter);
        if (!$counter) {
        $counter = 1;
        } else {
        $counter = $line[value]+1;
        }
        }
        $fp = fopen ($file, "w");
        fwrite ($fp, "$counter") ;
        fclose($fp);
        $fp = fopen ($file, "r");
        $count = fgets($fp);
        echo $count;
        ?>





        Comment

        • Andy Hassall

          #5
          Re: Reading from file basics

          On Fri, 19 Mar 2004 22:31:48 GMT, "deko" <dje422@hotmail .com> wrote:
          [color=blue][color=green]
          >> Looks like you're assuming visount contains a single line with a counter on
          >> it? You're missing file locking here - what if two people run the script at
          >> the same time? This is the sort of thing databases were invented for.[/color]
          >
          >I agree, a database could be used - but this is a traffic counter, and that
          >would mean a lot of overhead if I were using a database.
          >[color=green]
          >> Having said that, if you either put flock() calls in, or ignore the race
          >> condition, why are you re-opening the file and reading what you just wrote -
          >> just echo $counter back out?[/color]
          >
          >How do I ignore the race condition?[/color]

          The problem is you already are :-)
          [color=blue]
          >would that be better than using flock()?[/color]

          No. See Pedro Graca's post.

          --
          Andy Hassall <andy@andyh.co. uk> / Space: disk usage analysis tool
          <http://www.andyh.co.uk > / <http://www.andyhsoftwa re.co.uk/space>

          Comment

          Working...