i have to download a file created from a php script.
i tried this:
fopen('www.example.com/download.php?key=value', 'rb');
but i stille get a "failed to open stream" error.
how can i do that? If I browse to the url i get the file without problems...
EDIT: sorry, i forgot a piece of the string :)
I see multiple issues with you request:
You need to specify the open mode. In your case only 'r' applies because you only want to read.
You need to specify the protocol. In your case "http".
You need to have URL wrappers enabled. Do a phpinfo() and look if allow_url_fopen is set to On.
You probably wanted file_get_contents anyway.
You should enable error reporting and read the error messages. That will help you track the problem faster.
Don't forget to fclose if you decide to use fopen.
Example:
$data = file_get_contents('http://www.example.com/download.php?key=value');
You should also read about fopen in the Manual.
It looks like you need to read the usage for fopen first, here is an example usage:
fopen ("http://www.example.com/", "r");
r = read, that might be causing your failure.
Related
I'm trying to learn about creating web bots and I'm working my way through a book called Webbots, Spiders, and Screen Scrapers by Michael Schrenk. In the book he gives example code for a basic bot that downloads a webpage. I have copied the code exactly as it is in the book (sans comments):
<?
$target = "http://www.schrenk.com/nostarch/webbots/hello_world.html";
$downloaded_page_array = file($target);
for($xx=0; $xx<count($downloaded_page_array); $xx++)
echo $downloaded_page_array[$xx];
?>
I put this code in a php file and uploaded to my site. When I navigate to it in the browser however, nothing happens. It just loads a blank page. No content.
Earlier I tried another snippet that the author provided, again, this one was copied EXACTLY from the book, only with this one I didn't really get a blank page, the page just tried to load until it eventually timed out. Never got the correct content back:
$target = "http://www.schrenk.com/nostarch/webbots/hello_world.html";
$file_handle = fopen($target, "r");
while (!feof($file_handle))
echo fgets($file_handle, 4096);
fclose($file_handle);
I have checked the URL to make sure the file exists and it does. I have no idea why this wouldn't work. I've read through how to use the file(); and fopen(); functions in PHP but from what I can tell they are both being used correctly. What am I doing wrong here?
Accessing URLs via fopen() is a bad idea. It requires you to have allow_url_fopen enabled in your PHP config, which opens the door to a vast number of exploits (hosters disable it for a reason).
Try using cURL functions instead: they will give you much more flexibility and control. PHP documentation gives you some great examples to start with.
Not fgets($file_handle, 4096) but fread($file_handle, 4096) ;
$target = "http://www.schrenk.com/nostarch/webbots/hello_world.html";
$file_handle = fopen($target, "r");
while (!feof($file_handle))
echo fread($file_handle, 4096);
fclose($file_handle);
Then later if you want to create a new file from the extracted text :
// extracting text operation
$target = "http://www.schrenk.com/nostarch/webbots/hello_world.html";
$file_handle = fopen($target, "r");
$getText = fread($file_handle, 4096);
fclose($file_handle);
// writing file operation
$writeHandle = fopen ("folder/text.txt","w"); // file will be created if not existed
$writeFile = fwrite($writeHandle,$getText );
fclose($writeHandle );
First you should put error_reporting(E_ALL); ini_set('display_errors', '1'); to your script to enable displaying errors in your script as AbraCadaver mentioned in his comment.
A reason could be, that allow_url_fopen is disabled on your hosting.
This option enables the URL-aware fopen wrappers that enable accessing URL object like files. Default wrappers are provided for the access of remote files using the ftp or http protocol, some extensions like zlib may register additional wrappers.
See: http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
You can check that via:
var_dump(ini_get('allow_url_fopen'));
Your script requires true to run correct.
If allow_url_fopen is not true or 1 you can try to use file_get_contents() to load a url.
<?php
$homepage = file_get_contents('http://www.example.com/');
echo $homepage;
?>
See: http://php.net/manual/en/function.file-get-contents.php
I have a PHP code that connects to a FTP server, reads a file's content, makes a minor change, and than overrides the original file.
it looks like:
$stream_context = stream_context_create(array('ftp' => array('overwrite' => true)));
$file_content = file_get_contents($ftp_file); // this line works
$file_content = str_replace('some content', 'another content', $file_content); // this also..
file_put_contents($ftp_file, $file_content, 0, $stream_context); // this one doesn't :/
the real issue is that the "file_put_contents" worked for a long time, but now it doesn't.
what it does now is weird: it deletes the original file from the server..
also, if i'm changing it to something like:
file_put_contents($new_ftp_file, $file_content);
from what I know, it should create the new file and put the content in it, but it doesn't create it at all.
the hosting service i'm using has a PHP version change a few days ago. I don't remember the what the previous version was, but the current is: 5.2.17
thanks! :)
some changes
I found this piece: http://www.php.net/manual/en/function.file-put-contents.php#86864
doting the same as "file_put_contents" but with foen, fwrite and fclose (I send his example because of the results..). his functions is returning "false" if it couldn't to "fopen" the file, or the "bytes" if it succeeded. I got "false" :/
which means it couldn't even do the:
#fopen($filename, 'w');
although the "file_get_contents" with the same file address is working.
reading is working (but if you take the $filename and use it yourself on a client FTP - it works):
#fopen($filename, 'r');
the "open base_dir" for my hosting (which makes the action) is set to false, but the target hosting (which has the target-file) is set to be true.
I had an idea to save the new content on a new file, so I tried something like:
$f = #fopen($new_ftp_file, 'w'); //this one seems to work and connect
fwrite($f, $file_content); // this one seems to work either and returning the number of byes..
fclose($f);
the problem is that none of them really works. I logged in to the FTP address, using the same credentials that my script is using, and I haven't found the new file. It wasn't created at all. (as I remind you, "$new_ftp_file" is a path to a file that doesn't exists, so "w" mode on "fopen" should create it).
file_put_contents do erase the file by default if it already exists. You have to ask him to don't.
Look at here:
http://www.php.net/manual/en/function.file-put-contents.php
See: If filename does not exist, the file is created. Otherwise, the existing file is overwritten, unless the FILE_APPEND flag is set.
this is not the best solution (definitely), but I managed to figure something..
I used 2 different hosts on them same hosting service, both of the having "open base_dir = On" & "safe mode = Off".
it looks something like:
$ftpstring = "ftp://user:password#anotherhosteddomain.com";
$file = file_get_contents($ftpstring . 'index.html'); // this line works as expected. (yeah, the other hosting has this file);
and then, if you're trying to write something like:
$handler = fopen($ftpstring.'index.html', "w");
it wouldn't work, and tell you it cannot access on writing mode to an existing file.
so if you're doing something like:
$newfile_handler = fopen($ftpstring.'index_new_version.html', "w");
fwrite($newfile, "1122");
so yeah - it works!
but now is a tricky issue.. when i'm adding this line:
fclose($newfile_handler);
the new file is deleted from the hosting!!
I couldn't find any reason why "fclose" is deleting the file after it was create at "fopen" and written in at "fwrite".
so if you're not adding the "fclose" line - it works, but it doesn't close the connection, and also I have to actually delete the existing file before I can override it with a new content, which makes it silly..
although it works, I would really like someone to give me a better solution than mine.
I'm writing a system for a browser application that will store some particular php scripts in a database and then pull them out and execute them when needed. At first I tried using exec() and piping to php the output of a script that got the scripts out of the database and printed them. This worked in one use case, but not all, and feels brittle anyway, so I'm looking for a better way.
I'm now attempting to accomplish this through use of a PHP file stream in memory. For instance:
$thing = <<<'TEST'
<?php
$thing = array();
print "Testing code in here.";
var_dump($thing);
?>
TEST;
$filename = "php://memory";
$fp = fopen($filename, "w+b");
fwrite($fp, $thing);
//rewind($fp);
fclose($fp);
include "php://memory";
However, nothing is printed when the script is executed. Is this even possible by this means, and if not, is there another way to do this? I'm trying to avoid having to write temporary files and read from them, as I'm sure accessing the filesystem would slow things down. Is there a URL I can provide to "include" so that it will read the memory stream as if it were a file?
I don't think eval() would do this, as, if I remember correctly, it's limited to a single line.
Also, please no "eval = include = hell" answers. Non-admin users do not have access to write the scripts stored in the database, I know that this needs special treatment over the life-cycle of my application.
You need to use stream_get_contents to read from the php://memory stream. You cannot include it directly.
eval() and include are actually pretty the same. So eval() works with multiple lines - just FYI. However, I would prefer include here, I always think it's faster. Maybe I'm wrong, no Idea.
However, I think you should debug your code, I don't see a reason per-se why it should not work. You might need to rewind the pointer (you have commented that), but what you should check first-hand is, that your PHP configuration allows to include URLs. I know that that setting prevents using of the data:// URIs, so you might have this enabled.
Also you can always try if PHP can open the memory by using file_get_contents and dumping out. This should give you the code. If not, you already made some mistake (e.g. no rewind or something similar).
Edit: I've not come that far (demo):
<?php
/**
* Include from “php://memory” stream
* #link https://stackoverflow.com/q/9944867/367456
*/
$thing = <<<TEST
<?php
\$thing = array();
print "Testing code in here.";
var_dump(\$thing);
TEST;
$filename = "php://memory";
$fp = fopen($filename, "w+b");
fwrite($fp, $thing);
rewind($fp);
var_dump(stream_get_contents($fp));
This is what I found out:
You should not close the "file". php://memory is a stream once closed it will disappear.
You need to access the $fp as stream than, which is not possible for include out of the box AFAIK.
You then would need to create a stream wrapper that maps a stream resource to a file name.
When you've done that, you can include a memory stream.
The PHP settings you need to check anyway. There are more than one, consult the PHP manual.
It might be easier to use the data URI (demo):
<?php
/**
* Include from “php://memory” stream
* #link https://stackoverflow.com/q/9944867/367456
*/
$thing = <<<TEST
<?php
\$thing = array();
print "Testing code in here.";
var_dump(\$thing);
TEST;
include 'data://text/plain;,'. urlencode($thing);
See as well: Include code from a PHP stream
If there is a way to include from php://memory then this is a serious vulnerability. While it has many uses, eval is used quite often with code obfuscation techniques to hide malicious code.
(Every tool is a weapon if you hold it right.)
With that said, there (thankfully) doesn't appear to be any obvious way to include from php://memory
I have a file with the contents:
a:12:{s:12:"a2.twimg.com";i:1308768611;s:12:"a1.twimg.com";i:1308768611;s:12:"a0.twimg.com";i:1308768612;s:12:"a3.twimg.com";i:1308768612;s:8:"this.com";i:1308768613;s:15:"f.prototype.com";i:1308768613;s:15:"c.prototype.com";i:1308768614;s:15:"a.prototype.com";i:1308768614;s:5:"w.com";i:1308768615;s:5:"s.com";i:1308768615;s:5:"f.com";i:1308768615;s:5:"h.com";i:1308768615;}
(It's an array of domains listed on twitter.com as keys and a timestamp as values)
If I call:
unserialize(fread($recentfile, filesize("./neptune_output/recent")))
("./neptune_output/recent" is the location of the $recentfile)
It fails, but if I call unserialize with that string pasted in, it works.
I use the following code to open the file.
$recentfile = fopen("./neptune_output/recent", 'a+')
I've tried putting the fopen mode as 'c+' and 'a+b' but it won't work.
Do I need to post more code?
Why don't you just read it with file_get_contents() rather than messing about with opening it and working out the file size?
a+ means: "Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it."
If you just want to read "r" is enough:
$recentfile = fopen("./neptune_output/recent", 'r')
See http://nl2.php.net/manual/en/function.fopen.php
I'm having trouble with reading and writing the php://temp stream in PHP 5.3.2
I basically have:
file_put_contents('php://temp/test', 'test');
var_dump(file_get_contents('php://temp/test'));
The only output I get is string(0) ""
Shouldn't I get my 'test' back?
php://temp is not a file path, it's a pseudo protocol that always creates a new random temp file when used. The /test is actually being ignored entirely. The only extra "arguments" the php://temp wrapper accepts is /maxmemory:n. You need to keep a file handle around to the opened temp stream, or it will be discarded:
$tmp = fopen('php://temp', 'r+');
fwrite($tmp, 'test');
rewind($tmp);
fpassthru($tmp);
fclose($tmp);
See http://php.net/manual/en/wrappers.php.php#refsect1-wrappers.php-examples
Each time, when you use fopen to get handler, content of php://temp will be flushed. Use rewind() and stream_get_contents() to get content. Or, use normal cachers, like APC or memcache :)
Finally found a documented small note, that explains why
Example 5 at the PHP Manual used almost your exact same code sample and says
php://memory and php://temp are not reusable, i.e. after the streams
have been closed there is no way to refer to them again.
file_put_contents('php://memory', 'PHP');
echo file_get_contents('php://memory'); // prints nothing
I guess this means that file_put_contents() closes the stream internally, which makes file_get_contents() unable to recover the data in the stream again
I know this is late, but in addition to #OZ_'s answer, i just discovered that 'fread' works too, after you rewind.
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'I am freaking awesome');
fread($handle); // returns '';
rewind($handle); // resets the position of pointer
fread($handle, fstat($handle)['size']); // I am freaking awesome