Hi all,

I've got a page where I'm displaying images from a directory. The images are labled 1.jpg through 524.jpg. This will never change (i.e. names or numbers of images in this directory).
What i've added is a file that contains 'subtitles' to each image. It's just a text file in this format:

1|some words for image 1
2|some words for image 2
...etc

This is the code im using to display the subtitle with the appropriate image:

$subTitles "some/path/to/the/textFile";
$fo = fopen($subTitles, 'r');

if ($fo) {
	while (!feof($fo)) {
		$fContents = fgets ($fo,4096);
		list($fImgNum,$subtitle) = split ("\|",$fContents);
		if ($fImgNum == $imgNum) {
			echo $subtitle;
			break;
		} 
	}
	fclose ($fo);
} else {
    echo "Error opening the subtitles file";
}

this works fine for my purposes.

I'm wondering though, is there a way to fopen(), or file() then go directly to a specified line number instead of going through the file line by line until the current image/line number is reached? I realize that 524 lines is pretty tiny, but it just seems like there is a more 'direct' way to the line number needed?

Thanks.

    Using file(), why can't you just input the line number into the array?

    For example:

    $lines = file("file.txt");
    list($image,$description) = explode("|", $lines[523]);
    

    Of course the line numbers will be off by 1 considering file() will start at 0

      thanks for the reply m@tt!

      yup, that was the sort of thing I was looking for. I'm using this:

      $fContents = file($subTitles);
      list($fImgNum,$subtitle) = split ("\|",$fContents[$imgNum-1]);
      echo $subtitle;
      

      thanks for the suggestion.

        That way will work fine, but you'll still be loading the entire file, even for retrieving one line. For another way, you could ensure that all the file's lines are the same length (e.g. with str_pad()), then use fseek() to get a particular line. Of course, databases are popular for a reason.

          thanks for the reply Installer.

          unfortunately, most lines will be different in length (perhaps only 5% will be exactly the same in length).

          while i could have used a database for this, i didn't want to have to query the table for each image that was loaded. i thought that was unnecessary overhead. Now, if there's a way to cache all the images' subtitles, or load them all into a session array (?) or something like that, then I guess that would call for only 1 query. But then I would need to access this new object for each image loaded.
          Perhaps there is a way to do this with OO PHP?

            unfortunately, most lines will be different in length

            Hence Installers suggestion of using [man]str_pad[/man] to make them the same length.

              got it. obviously i've never used str_pad. from the post, i read it as "I" would need to make each line the same length.

              i'm wondering though, with 524 lines (max length < 100 characters) in this file which is more 'overhead?'

              loading that small file into an array, then going to the index number?
              or
              padding each of the 524 lines (some with as few as 10 characters) with, at least, spaces and then using fseek to go to the particular line? Also, this method would require at least one fopen...right?

              i'm obviously not an expert php coder, but the 2nd choice seems to be more work or overhead in the process (even though it would be very very small in either case).

                You would need to do only a one-time padding of all the lines, then when and if you add new lines simply pad each one when it's added. Of course, the amount of disk space used would depend on how many short lines compared to how many long lines you have. But even if it's a high ratio, you'd still be saving on memory consumption (loading one line vs. loading all lines).

                Not to beat a dead horse, but I don't see how any of these solutions involve less overhead than using a db.

                  understanding it more now.

                  regarding these solutions vs a db one, i indicated that i 'thought' it would be more overhead. i haven't had the time, nor the knowledge on how to benchmark them.

                  is a query to a table 'less expensive' than this fseek option to a 4kb file? my particular scenario is 524 images that users can click through. in the end, if someone clicks through all 524 images...is 524 queries better than 524 fseek's?

                    Write a Reply...