Puzzling dilemma with fopen()

Hi all,

I’m changing a site. Currently I’m changing the PHP script that generates a RSS file from a PHP file via reading the latter into a buffer then disecting its data to then write to a new XML file.

Before I was opening a source PHP file online. Now, I’ve changed the path to open the source PHP file be it localhost or online.

$rss_from_file= $_SERVER[‘DOCUMENT_ROOT’].‘/online-auto-news/ford/ford-auto-news.php’;

//open source and destination files
$rss_source_file = fopen(“$rss_from_file”, “r”) or die(“can’t open file [SOURCE]”);
$rss_write_file = fopen(“$rss_to_file”, “a”) or die(“can’t open file [DESTINATION]”);

//read the entire contents of source file into buffer
while (!feof ($rss_source_file))
	$source_file_contents = fgets($rss_source_file);			
$source_file_array_count = sizeof($source_file_contents);

The good news:
$rss_source_file reports “Resource Id #4” and opens the source PHP just fine

The bad news:
ford-auto-news.php is a long file, i.e, a couple hundred lines of code. When I however test for $source_file_array_count it will always report “1” suggesting that only one line from the source PHP has been read into $source_file_contents. This is indeed the case because if I echo out $source_file_contents I will always get “</html>” hence the absolute last line of code in the source PHP file.

The problem:
Basically, why is it opening the file ok, even reading the data within the file but only reading the last line thus causing the $source_file_contents to be “1”. This naturally makes the rest of the script fall over given it looks for tags nested within the source PHP file.

$rss_from_file always reports a valid path to the source PHP file, which is as I’ve said above, proven by the fact that $rss_source_file reports “Resource Id #4” on fopen().

This script worked absolutely fine when $rss_from_file was provided in the form of “http:\\www…etc”.

Logically one could say it’s opening the file ok, reading the file ok but somehow only skipping to the last line in the file, i.e. while (!feof ($rss_source_file)) always loops only once.

Anyone know what’s up?

Thanks a lot.

while (!feof ($rss_source_file))
  $source_file_contents = fgets($rss_source_file);			

for ($x=0; $x<10; $x++)

What is $a at the end? Do you see what I’m getting at? :slight_smile:

Exactly, that’s why I thought I’ll keep it all local and save myself more work on each major content update.

You guys are probably thinking I’m making a big problem out of a small issue and while I agree and see your line of thinking, there’s still this to address:

a) even if the PHP source file isn’t executed, be it fopen() or file_get_contents() should still get all code within that PHP source file and not just </html> as it’s doing now (i.e. array size = 1) as something is forcing it to skip to EOF from the get go.

b) either 1) upload the source PHP file and read it as http:// etc. or 2) force execute the PHP locally and read the rendered page into a variable instead of using fopen() or file_get_contents().

At the moment I’m researching into b), namely seeing how reliable it would be to use shell_exec().

If you have local access to php files, you have local access to the database or any other part of the site. If you got all that, where’s the problem? :slight_smile:

More food for thought, thanks.

I’ll try shell_exec() and see how that works, API will require more thinking.

The whole point of giving it a local path was to reduce the number of steps necessary to update the website’s data. Uploading various files, all in seperate folders just to render XML files offline to then upload them too is a little tedious on a larger website.

I guess I was trying to skip the gun too fast too soon.

Well exactly, if you use fopen or file_get_contents and don’t specify URL but a local path - you retrieve file contents, not the thing you want when it gets executed. That’s why you should change the approach to your problem. If you can access the .php file locally, you can write some code to give you the same output.
Quick and dirty solution is to actually force execution with shell_exec() or exec(), however there’s no guarantee the script will work (depending on what other files it expects included) and so on.

Hence, you should change the approach to your problem and forget about that file. That’s why OOP comes in handy or writing APIs. If you’re not advanced enough to do so yet, maybe quick and dirty solution - use URL instead of local path like you used to and that’s it.

Thanks for sharing your time.

Right, you make a simple but very valid point I reckon, of course I’ll upload a copy of the PHP file and try what you say but seems promising.

Either way the PHP file needs to get executed to be populated with data which can then be extracted into a RSS compatible XML file. Knowing this is a given (can’t be avoided) it should work on localhos or online. The only question is forcing the PHP file to get rendered and only then to be read (not before).

file_get_contents() will read the entire file in one go (quicker, better perhaps) but this doesn’t change the fact that the PHP file needs to be executed prior to being investigated for data to then pull out of it and paste into an XML RSS type file.

Thanks for your thoughts. Yes, I see what you’re getting it, i.e. that $a will the last value of $x.

Sadly while (!feof ($rss_source_file)) as I wrote above only ever executes once so at least in this case this isn’t the problem.

What’s puzzling is that even if the PHP file doesn’t get executed, there’s a lot of normal html in there and CSS that should get read anyhow. PHP is only used to dynamically render inline data. There’s so much more than </html> in there. It should read in the <h1>'s, <h2>, <p> DIV’s styles etc.

If you open a URL, the file will get executed and you’ll get the xml it’s designed to display.
If you open the file locally, like you did, you’ll get php code and not the xml data the php provides you with. You’re not executing the php file with your fopen, you’re just fetching what’s stored in it.
Also, check www.php.net/file_get_contents

Maybe you should change your approach to the problem.