Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sorting

Status
Not open for further replies.

DreamerZ

Programmer
Jul 11, 2001
254
US
I have looked at the information regarding array sorting on the PHP.net site, but I'm not sure that's what I want to or can even do in this case.

I have a flat file(.txt) where each line is a separate piece of data like below:

Name^Date^Time^Code

Currently, the data MUST be entered in DATE order, i.e. 7/2/04 then 7/3/04 then 7/6/04. If the dates are entered out of order, the whole thing goes to hell rather quickly.

Obviously, that's a problem.

So, I want to be able to locate the place where the data should be entered into the file.

File:
Joe^7/1/04^10^1
Joe^7/2/04^14^5
Joe^7/6/04^8^7

Entry = Joe^7/3/04^16^2

The Entry should be placed after 7/2/04 and before 7/6/04.

Currently, this is where I'm at:
Code:
if(!($fp_opFile=@fopen("$abs_Operator.txt","r")))
  {
    echo "<script> alert('File Error.  Contact Support');
    window.location='bstAbsence.phtml'</script>";
  }
  else
  {
    $tmp_fp = fopen("tempfile.txt","a");
    while (@!feof($fp_opFile))
    {
	$opInfo = @fgets($fp_opFile);
	$fields = explode("^",$opInfo);
	if (trim($abs_OLDInfo) != trim($opInfo))
	{
	  if (strtotime($fields[1]) < strtotime($abs_Date))
	  {
	    fwrite($tmp_fp, $opInfo);
	  }
	  else
	  {
	    fwrite($tmp_fp,$abs_Info);
	    fwrite($tmp_fp, "\n");
	  }
	}
    }
    fclose($tmp_fp);
    fclose($fp_opFile);
    //rename("tempfile.txt", "$abs_Operator.txt");
  }
$abs_Date = the Entry Date and $fields[1] = the File Date

Thoughts? How do I proceed?

TIA

DreamerZ
 
use mysql.

sorry but its a whole lot easier.
Otherwise you are looking at opening the file, renaming it so it cant be accessed by another session, reading each line, and writing them back out including the new line, then closing the file and hoping no-one else wanted to update it in the mean time.

______________________________________________________________________
There's no present like the time, they say. - Henry's Cat.
 
Yeah, you should just use a database here... then you can write a simple script which will dump that database to your text file nicely sorted in case that text file is the output you actually need.

SQLite is likely sufficient if you're willing to use PHP5RC3 and don't want to bugger around with a MySQL installation.
 
hi,
if you must use flat files (use a database!!) you could use something like:
Code:
$fp = fopen("your file.txt", "r");
$filearray = file($fp);

foreach($i=0;$filearray; $i++)
{
  $newarray[$i] = explode("^", $filearray[$i]);
}

usort($newarray, sortit);

The above should read your file line by line and store it in an array.

Split the array using explode and store the results in a new array $newarray = array( array ("Joe", "date", "time", "code"))

Now use the usort function to sort the multidimensional array (see below for the function used in usort)

(sorry I have not been able to test and my foreach understanding may be incorrect but still a pointer in the right direction)

Code:
function sortit($x, $y)
{
  if(strtotime($x[1]) == strtotime($y[1]))
    return 0;
  elseif(strtotime($x[1]) < strtotime($y[1]))
    return -1;
  else(strtotime($x[1]) > strtotime($y[1]))
    return 1;
}
This function compares two values of the defined field (1=date) and sorts the array on date order.

I would now delete the existing file (or rename it to something like 'today's date and time - name of file' for backup).

Now it is on you to write this array back to a file (use the name of your delete file?

I hope this works or at least helps!


JR
As a wise man once said: To build the house you need the stone.
Back to the Basics!
 
A database is not an option. I work for a big company with lots of red tape and other "Projects" to get something like this to happen. We use Oracle for other things, but I'd have to show the value before efforts were made to use it. Which, BTW, I'm trying to do.

While the array path might be better, more efficient, and/or more stable, the code below is what I did:

Code:
if(!($fp_opFile=@fopen("$abs_Operator.txt","r")))
  {
    echo "<script> alert('File Error.  Contact Support');
    window.location='bstAbsence.phtml'</script>";
  }
  else
  {
    $written=0;
    $tmp_fp = fopen("tempfile.txt","a");
    while (@!feof($fp_opFile))
    {
    $opInfo = @fgets($fp_opFile);
    $fields = explode("^",$opInfo);
    if (trim($abs_OLDInfo) != trim($opInfo))
    {
 if ($written==0 && strtotime($abs_Date) < strtotime($fields[1]))
	  {
	    fwrite($tmp_fp, $abs_Info);
	    fwrite($tmp_fp, "\n");
	    $written = 1;
	  }
	  fwrite($tmp_fp,$opInfo);
	}
    }
    if (!($written))
    {
	frwite($tmp_fp, $abs_Info);
	$written = 1;
    }
    fclose($tmp_fp);
    fclose($fp_opFile);
    //rename("tempfile.txt", "$abs_Operator.txt");
  }

It works fine and is just a few lines.


DreamerZ
 
Just wondering where your $abs_date comes from?
And are you sure it does not just sort the time and does actually also move the other fields like:

Joe^7/1/04^10^1
Jr^7/2/04^12^20

should not become (or should it)?

Joe^7/2/04^10^1
Jr^7/1/04^12^20

JR
As a wise man once said: To build the house you need the stone.
Back to the Basics!
 
$abs_Date is a form field from where this information is submitted. It is a part of a larger array ($abs_Info) of information. What's written is the full array with just the $abs_Date and $fields[1] (which is the date already in the file) being compared.

When the if statements are evaluated, it's the larger arrays that are written, so the full line ($abs_Info or $opInfo) and not just the dates.


DreamerZ
 
Your database is not an option makes SQLite the perfect option for you! Cause it just installs with PHP5... the downside as I mentioned is the whole RC part.

But enough trying to convince you about that. I don't think the code you posted will work... unless you've left alot out. Perhaps I'm just not seeing things, but I see comparisons to uninstantiated variables, as well as the writing out of other uninstantiated variables to files.

Plus, and correct me if I'm wrong, I think you're attempting to implement a sort of bubblesort here? Which means you'll need to re-run it over and over until no changes are made...unless you're thinking you'll sort the file, then run it everytime a new record is added?

Personally, I'd say if you must do this with flatfiles, there's no way with even reasonable performance on large files to do it outside of an array sort.

Also, have you considered using XML over flatfiles, not so much for the sake of your or your code right now... but for the sake of passing this data down the line?
 
As I said, I cannot install anything extra, so that's not an option.

Yes, I did leave A LOT out and yes, what I've coded does work fine. Again, it might not be the most stable in the long run, but I am hoping to have enough of an impact over our current system that the higher ups at least look at this as an option and move it to the Oracle DB that we currently use other things for.

BTW, our current system is pen and paper with 5 different locations of data all of which written by hand and different people. So, while this isn't the best of options, it is a start and certainly a better option than our current system.


DreamerZ
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top