PDA

View Full Version : PHP - stream_context_create




larswik
Jun 26, 2012, 02:24 PM
I have a PHP script that I wrote and worked well. The other day I made a few modifications and Firefox gave an error and said it reset the connection or something like that. I started to comment out the code to find the problem area and it was a fopen

$fp_read = fopen($pathToFile, "w");

I googled looking for the answer which I found a number of results. Someone posted this code which Incorporated into my code and that fixed my problem but it did not explain what was happening?


$context = stream_context_create(array('ftp'=>array( 'overwrite' => true)));
$fp_read = fopen($pathToFile, "w", false, $context);


I looked at the PHP site for the description and it was only 1 sentence, "Creates and returns a stream context with any options supplied in options preset. "

I am still trying to understand what this function is doing which allowed my code to work. I am happy that it works but I want to know why so I understand it better.

Thanks



jared_kipe
Jun 26, 2012, 02:52 PM
is $pathToFile something like 'ftp://someurl/'?

larswik
Jun 26, 2012, 04:27 PM
Yep


$dayLocation = 'ftp://user:password@someSite.com/public_html/app/daysForTicker/%'.'.txt';
$pathToFile = str_replace('%', $dayOfWeek, $dayLocation);

jared_kipe
Jun 26, 2012, 06:21 PM
So basically fopen() and file_get_contents() have some kind of default behavior for the various protocols they can work with. You create and use stream contexts to modify or add behaviors of those various protocols (http, ssl, ftp...).

Here is a list of the Context options and parameters. http://www.php.net/manual/en/context.php

Does that make sense?

larswik
Jun 27, 2012, 12:46 AM
Your link lead me to this link http://www.php.net/manual/en/stream.contexts.php which is at the heart of what I am trying to get. What do they mean by the term "stream".

When I think of Stream I think of the time data is being set to when it stops. The data is being streamed like a stream of water next to my house.

With fopen it seems to take upto 4 arguments. URL location, the mode, use_include_path which seems to search for the file and then the Context as the 4th argument.

I think I need to find some examples of those so it sinks in better.

Thanks for the help jared_kipe

jared_kipe
Jun 27, 2012, 01:16 PM
Streams are basically 'abstract' data devices, i.e. you don't need to know the intricacies of the individual device (hard drive, cd-rom...) or protocols (http, ftp...). The idea is that you open/create a stream, then read or write to that stream.

URL locations, can be generic files 'path.php', or resource locators including protocols 'ftp://host/path.php'.

The mode generally relates to normal file paths, and depend on if you want to read, write, or append data to a file.

use_include_path is PHP specific and just relates to where 'path.php' can be found.

And again the stream_context tells the runtime/OS how to use/modify the options for your protocol.

larswik
Jun 27, 2012, 02:29 PM
Ok I kind of see what you are saying. What was confusing was just the fopen.


$fp_read = fopen($pathToFile, "w");


It seems pretty straight forward. It opens a connection to the file on the remote server and I set the mode "w". But if I understand what you are saying there are settings above and beyond that you can set up in the steam context when I open a stream to read or write to. In this case I am setting the "overwrite" to TRUE and then this becomes one of the arguments for the fopen that sets up some parameters for the stream that is being created or read from?

Did I get that for the most part?

Thanks again for taking the time to explain this. I hate copying and pasting code from the internet and not knowing what it does or why it works. I don't learn then.

jared_kipe
Jun 27, 2012, 05:31 PM
Ok I kind of see what you are saying. What was confusing was just the fopen.


$fp_read = fopen($pathToFile, "w");


It seems pretty straight forward. It opens a connection to the file on the remote server and I set the mode "w". But if I understand what you are saying there are settings above and beyond that you can set up in the steam context when I open a stream to read or write to. In this case I am setting the "overwrite" to TRUE and then this becomes one of the arguments for the fopen that sets up some parameters for the stream that is being created or read from?

Did I get that for the most part?

Thanks again for taking the time to explain this. I hate copying and pasting code from the internet and not knowing what it does or why it works. I don't learn then.

Correct, a lot of things go on in the background when you use fopen() with a URL that isn't a local file (at least compared to C's fopen()).

In this case you are setting 'ftp's overwrite flag to true. Which... I suspect is similar to using the normal file mode 'w+' meaning overwrite (truncate) or create new file.
EDIT: I suspect this because my gut/intuition tells me the FTP protocol does not allow for opening a file to edit it and save it in place, I think its only upload/overwite and download/read.

larswik
Jun 28, 2012, 03:15 AM
Gotcha, thanks for the clarification!

chown33
Jun 28, 2012, 12:20 PM
EDIT: I suspect this because my gut/intuition tells me the FTP protocol does not allow for opening a file to edit it and save it in place, I think its only upload/overwite and download/read.

FWIW, FTP also has an "append" mode. Not at all useful in this case; I've just been working with FTP lately.

http://en.wikipedia.org/wiki/File_Transfer_Protocol#List_of_FTP_commands

jared_kipe
Jun 28, 2012, 12:38 PM
FWIW, FTP also has an "append" mode. Not at all useful in this case; I've just been working with FTP lately.

http://en.wikipedia.org/wiki/File_Transfer_Protocol#List_of_FTP_commands

Very true, and I certainly didn't know that. That said, looking through the list I don't see anything that would allow for opening->editing->saving locally other than downloading, editing, uploading the full file. Which makes total sense to me.

larswik
Jun 28, 2012, 02:28 PM
I was using the append mode before


$fp_read = fopen($URL_ToWrite, "a");


But it placed the pointer at the end of the file and wrote data there where I needed everything rewritten. So I deleted the file first to solve this problem using this code


if (file_exists($URL_ToWrite)) {
unlink($URL_ToWrite); //deletes the file if it is there.
echo '----Update_check.txt File Exists to write'.'<br>';
echo "$URL_ToWrite";
}


But even though I checked for the file sometimes it would return false and skip the IF statement. In this case it appended the file and added identical information. I decided then not to delete the file and to just overwrite the information.

I found other code online that checked to see if the file existed by verifying some HTTP header information. But it seemed logical that if the file was there a TRUE would be returned in the "file_exists" function.

EDIT: I think I had an "AH HA" moment with The term "Context" from above. Many months ago I followed a making a PDF tutorial. They referred to it as a "context", or the document they were going to create if memory serves me right.

jared_kipe
Jun 28, 2012, 03:08 PM
EDIT: I think I had an "AH HA" moment with The term "Context" from above. Many months ago I followed a making a PDF tutorial. They referred to it as a "context", or the document they were going to create if memory serves me right.

Yes, a context usually (always?) refers to a set of options, usually to setup before performing some action.

The PDF creation is analogous to Objective-C's CoreGraphicsContext (CGContextRef). You setup things like the font, color, line thickness, and then perform actions like adding shapes or text. Those added shapes or text will pickup the preciously set options for font, color, line thickness etc.

In the fopen() example, you setup the context, or options, for the FTP connection prior to making the connection so that the created connection has the options you need.

I think context's are practically the definition of 'programming with consequences' or the imperative programming paradigm.

EDIT: Also, especially if english is your primary language, think about what context is for natural language, especially with slang. 'That is a fat man.' is so vastly different to 'That was fat, man.' Just as surrounding words and punctuation improve the versatility of the word 'fat', the PHP stream_context improves the versatility of the fopen() function.

larswik
Jun 28, 2012, 10:00 PM
I get it now.

Thanks you for the detailed responses.