Page 1 of 1

help a very very fresh PHP programmer..

Posted: Thu May 15, 2003 8:42 am
by undo
Hi there,

I am not a PHP programmer but I have to run a php script urgently.

I had two variables "Data" and "ID".

"Data" is loaded from a file db.txt and contains data formatted like this: "120*2*23*2". i,e,a number of numbers separated by *.
ID contains a pointer to an entry in "Data" variable. for the above example if ID = 0 then the requested number is 120. if ID=1 then requested number is 2 and so on.

after reading the entry I want to increment it by one and save it back in db.txt.

can you help me??

here's the code I use:

<?
$filename = "db.txt";
$fp = fopen( $filename,"r");
$Data = fread($fp, 80000);
fclose( $fp );

$DataArray = split ("*", $Data);

$DataArray[$ID] = $DataArray[$ID] + '1';
$DataArray[0] = $DataArray[0] + '1';

#$fp = fopen( $filename,"w+");
#fwrite($fp, , 80000); #what should I put here???
#fclose( $fp );

print "&counter=$DataArray[$1]&sign_counter=$DataArray[0]";
?>

problem is: the code doesn't work and always returns false numbers (actually always returns ones)

Posted: Thu May 15, 2003 9:22 am
by volka
you might join the data-array again and write the string back

Code: Select all

$writeback = join('*', $DataArray);
fputs($fp, $writeback);
perhaps you should take a look at http://php.net/flock, too

Posted: Thu May 15, 2003 11:06 am
by lc
I'd do it like this, but it may not be the most efficient way

Code: Select all

<?php

$filename = "db.txt";

$Data = file("$filename");

$DataArray = explode("*", $Data[0]); 

$DataArray[$ID] = ("$DataArray[$ID]" + "1"); 
$DataArray[0] = ("$DataArray[0]" + "1"); 


$fp = fopen("$filename","w+"); 
flock ($fp,2);
foreach ($DataArray as $key){
$fw = fwrite($fp,"$key*");
} 
#fclose( $fp ); 

print "&counter=$DataArray[$ID]&sign_counter=$DataArray[0]"; 
?> 
?>

Posted: Thu May 15, 2003 7:50 pm
by undo
Dear Ic,
thanx a lot for ur help. I haven't tested the code yet because my server is down.

however, can u help me in similar scripts?? more details here: viewtopic.php?p=39986#39986

Posted: Fri May 16, 2003 1:33 am
by undo
hi Ic,

your script works great, but I have a problem.

the element $DataArray[0] returns 0 sometimes although it should return a non zero value. this resets the counter to beginning, Do you know why??

this php script may be called multiple of times from the same page, may this be the reason??

Posted: Fri May 16, 2003 2:42 am
by undo
I read this article about flock, and I found that it's a very big problem in PHP. I can't believe that PHP can't handle such a simple function.

article located at:
http://www.php.net/manual/en/function.flock.php

Posted: Fri May 16, 2003 3:39 am
by volka
:?:
you can handle it ..with flock
or did I miss something?

Posted: Fri May 16, 2003 3:53 am
by undo
Hi volka,
the script written by Ic uses flock. but it didn't solve the problem. the script is in Ic message. please check it for suggestions.

Posted: Fri May 16, 2003 4:41 am
by volka
the reader has to be blocked as well, e.g.

Code: Select all

<?php

$filename = 'db.php';
$fp = fopen($filename, 'r+b') or die('file not found: '. $filename);
flock($fp, LOCK_SH);

@include($filename);
if (!isset($arr) || gettype($arr) != 'array')
{
	$arr = array();
	$count = 0;
}
else
{
	$count = $arr[0] + 1;
	unset($arr[0]);
}
	
$arr[] = date('D M j G:i:s T Y');


flock($fp, LOCK_EX);
fseek($fp, 0, SEEK_SET);
fputs ($fp, '<?php $arr=array(');
fputs ($fp, "0=>$count");

foreach($arr as $key=>$value)
	fputs($fp, ", '$key'=>'$value'");
fputs($fp, '); ?>');
flock($fp, LOCK_UN);
?>

Posted: Fri May 16, 2003 7:06 pm
by undo
thanx volka,

Although I didn't understand a bit of the code. but I think I got the main idea.

I will test it and tell u>

thanx again

gazakom allah khairan

Posted: Sat May 17, 2003 1:39 am
by volka
yeah, I really should comment scripts

Code: Select all

<?php

$filename = 'db.php';
// flock needs a filedescriptor, so open the file now for read/write operations
$fp = fopen($filename, 'r+b') or die('file not found: '. $filename);
// try to acquire a read lock before...
flock($fp, LOCK_SH);
// ...the file is included (as php-script, description below)
@include($filename);

/* the contents of $filename has been parsed, it should define an
  array $arr that contains all values we need
*/
if (!isset($arr) || gettype($arr) != 'array')
{
   // but it doesn't, maybe a new file?
   // to die() here is another option
   $arr = array();
   $count = 0;
}
else
{
   // the first element of the array it the total counter
   $count = $arr[0] + 1;
   // remove the element here as it written "manually" afterwards
   unset($arr[0]);
}

// adding something to the array, since this is an example simply the current date is appended   
$arr[] = date('D M j G:i:s T Y');

// try to acquire a write lock, this will lock out the previous LOCK_SH if a seconds request arrives as long this one is beeing processed
flock($fp, LOCK_EX);
// rewind the file
fseek($fp, 0, SEEK_SET);

// the output is a php-script definining an array (let the php-parser do the work  )
fputs ($fp, '<?php $arr=array(');
// first element is the total count, let's do it "manually"
fputs ($fp, "0=>$count");

// each remaining element is written to the "array-script"
foreach($arr as $key=>$value)
   fputs($fp, ", '$key'=>'$value'");

// array done, script done
fputs($fp, '); ?>');

// release the lock (although this happens automagically when the script ends), an outstanding request now can get the LOCK_SH
flock($fp, LOCK_UN);
?>