Alternative way to read raw I/O stream in PHP - php

I am trying to find an alternative to reading php://input. I use this for getting XML data from a CURL PUT.
I usually do this with:
$xml = file_get_contents('php://input');
However, I'm having a few issues with file_get_contents() on Windows.
Is there an alternative, perhaps using fopen() or fread()?

Yes, you can do:
$f = fopen('php://input', 'r');
if (!$f) die("Couldn't open input stream\n");
$data = '';
while ($buffer = fread($f, 8192)) $data .= $buffer;
fclose($f);
But, the question you have to ask yourself is why isn't file_get_contents working on windows? Because if it's not working, I doubt fopen would work for the same stream...

Ok. I think I've found a solution.
$f = #fopen("php://input", "r");
$file_data_str = stream_get_contents($f);
fclose($f);
Plus, with this, I'm not mandated to put in a file size.

Related

Why fread (PHP) don't read entire file?

I have this code on PHP that load a local file:
$filename = "fille.txt";
$fp = fopen($filename, "rb");
$content = fread($fp, 25699);
fclose($fp);
print_r($content);
With this code I can see all the contents of the file. But when I change the $filename to a external link, like:
$filename = "https:/.../texts/fille.txt";
I can't see all the contents of the file, he appears cut to me. Whats the problem?
The fread() function can be used for network operations. But network connections work different than file system operations. A network cannot read a bigger file in a single attempt, that is not how typical networks work. Instead they work package based. So data arrives in chunks.
And if you take a look into the documentation of the function you use then you will see that:
Reading stops as soon as one of the following conditions is met:
[...]
a packet becomes available or the socket timeout occurs (for network streams)
[...]
So what you observe actually is documented behavior. You need to continue to read packages in a loop to get the whole file. Until you received an EOF.
Take a look yourself: https://www.php.net/manual/en/function.fread.php
And further down in that documentation you will see that example:
Example #3 Remote fread() examples
<?php
$handle = fopen("http://www.example.com/", "rb");
if (FALSE === $handle) {
exit("Failed to open stream to URL");
}
$contents = '';
while (!feof($handle)) {
$contents .= fread($handle, 8192);
}
fclose($handle);
?>

PostgreSql Large Object to file through PHP PDO

This code outputs LO to browser:
...
$my_pdo_connect->beginTransaction();
$stream = $my_pdo_connect->pgsqlLOBOpen($oid, 'r');
fpassthru($stream);
...
But I stuck with writing LO to file system.
I am aware about pg_lo_export and lo_export, but there is
restriction to use PHP PDO capabilities only.
Obviously I should use some php-function instead of fpassthru($stream) to write the stream into a file, can't find suitable docs or example.
Finally I found how to solve the issue:
$my_pdo_connect->beginTransaction();
$stream = $my_pdo_connect->pgsqlLOBOpen($oid, 'r');
$file = fopen('my_file', 'w');
stream_copy_to_stream($stream, $file);
fclose($file);

file_get_contents subtitute function or methods?

In one's server, file_get_contents is disabled for security reasons. I need to retrieve xml data. So, what is the best thing to do to :
Verify that file_get_contents is supported by a server ?
Is there any subtitute methods of file_get_contents ?
You can check whether or not you can use url's in file_get_contents() (and the fopen() family of functions) by checking the ini directive allow_url_fopen:
ini_get('allow_url_fopen');
You can get around these restrictions by using:
cURL
fsockopen()
I strongly recommend cURL. fsockopen() is a lot dirtier.
http://www.phpbuilder.com/board/showthread.php?t=10349521 - this seems to be a releavant topic
I would try to use simply fopen and fread functions.
First approach:
$bufferSize = 1024;
$file = fopen($file,'r');
while($cont = fread($file, $bufferSize)){
$file_content .= $cont;
}
fclose($file);
var_dump($file_content);
Second approach:
$filename = "/usr/local/something.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);

Best way to download a file in PHP

Which would be the best way to download a file from another domain in PHP?
i.e. A zip file.
The easiest one is file_get_contents(), a more advanced way would be with cURL for example. You can store the data to your harddrive with file_put_contents().
normally, the fopen functions work for remote files too, so you could do the following to circumvent the memory limit (but it's slower than file_get_contents)
<?php
$remote = fopen("http://www.example.com/file.zip", "rb");
$local = fopen("local_name_of_file.zip", 'w');
while (!feof($remote)) {
$content = fread($remote, 8192);
fwrite($local, $content);
}
fclose($local);
fclose($remote);
?>
copied from here: http://www.php.net/fread
You may use one code line to do this:
copy(URL, destination);
This function returns TRUE on success and FALSE on failure.

Whats a better way to write this function. Its gets a remote file and copys it localy, in php

So yea, im working on a windows system and while this works locally, know it will break on other peoples servers. Whats a cross platform way to do the same as this
function fetch($get,$put){
file_put_contents($put,file_get_contents($get));
}
I don't see why that would fail unless the other computer is on PHP4. What you would need to do to make that backwards compatible is add functionality to provide replacements for file_get_contents & file_put_contents:
if(version_compare(phpversion(),'5','<')) {
function file_get_contents($file) {
// mimick functionality here
}
function file_put_contents($file,$data) {
// mimick functionality here
}
}
Here would be the solution using simple file operations:
<?php
$file = "http://www.domain.com/thisisthefileiwant.zip";
$hostfile = fopen($file, 'r');
$fh = fopen("thisisthenameofthefileiwantafterdownloading.zip", 'w');
while (!feof($hostfile)) {
$output = fread($hostfile, 8192);
fwrite($fh, $output);
}
fclose($hostfile);
fclose($fh);
?>
Ensure your directory has write permissions enabled. (CHMOD)
Therefore, a replacement for your fetch($get, $put) would be:
function fetch($get, $put) {
$hostfile = fopen($get, 'r');
$fh = fopen($put, 'w');
while (!feof($hostfile)) {
$output = fread($hostfile, 8192);
fwrite($fh, $output);
}
fclose($hostfile);
fclose($fh);
}
Hope it helped! =)
Cheers,
KrX
Shawn's answer is absolute correct, the only thing is that you need to make sure your $put varialable is a valid path on either the Windows Server on the Unix server.
well when i read your question I understood you wanted to bring a file from a remote server to your server locally, this can be done with the FTP extension from php
http://www.php.net/manual/en/function.ftp-fget.php
if this is not what you intent I believe what shawn says is correct
else tell me in the comments and i'll help you more
If the fopen wrappers are not enabled, the curl extension could be: http://php.net/curl

Categories