fseek()
There is this nifty function in PHP called fseek(). It allows you to set a pointer to any where in a file (a text file for example). It comes in handy when your dealing with very large files (like log files, or config files), and today I discoverd it can be very useful if you want to search throu a file backwards.
Which was exactly what I was trying to do. I needed to traverse a file, starting at the end. The only solutions I could find infolved reading the whole file into an array, reversing the array and thensearching that way, which completly nullified the point of going the end of the file (I had to read the whole file into memory to get the end).
The solution I came up with, involves using fseek() and fread() (which allows you to read a file byte by byte). With this function you give it a file, and a string to search for, and it’ll go through the file backwards byte by byte, and return the pointer (byte location in the file) of where the search string occures. (if it doesnt find the string, it’ll return FALSE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <?PHP function searchFromEnd($filename,$search){ //first make sure that the file is there, and we can read it if(file_exists($filename) && is_readable($filename)){ //open the file for reading $fp = fopen($filename,'r'); //get the length of the search string(minus the first character) $size=strlen($search)-1; //get first element in string $first=$search[0]; //size of the file $file_size=filesize($filename); //set seek pointer to end of the file - size of the string $seek=$file_size-$size; //set found to FALSE $found=false; //while not past the begining of the file while($seek>=0){ //set file pointer to seek value fseek($fp,$seek); //read in the first byte from pointer $test=fread($fp,1); //if byte is same as the first string character, and back far enough in file for search length if($test==$first && (($seek+$size) <= $file_size) ){ //append enough characters to $test to make it same size as $search $test.=fread($fp,$size); //if test value is what we're looking for if(strcmp($test,$search)==0){ //return position; $found=$seek; //set pointer to -1 (exit loop); $seek=-1; }else{ //move back a byte $seek--; } }else{ //move back a byte $seek--; } } //close the file fclose($fp); } //return FALSE or position of search string return $found; } ?> |
A much better method then reading the whole file.
You can download this file from here
