I am using the output of a php file on a remote server, to show content on my own web-site. I do not have access to modify files on the remote server.
The remote php file outputs java script like this:
document.write('<p>some text</p>');
If I enter the url in a browser I get the correct output. E.g:
https://www.remote_server.com/files/the.php?param1=12
I can show the output of the remote file on my website like this:
<script type="text/javascript" src="https://www.remote_server.com/files/the.php?param1=12"></script>
But I would like to filter the output a bit before showing it.
Therefore I implemented a php file with this code:
function getRemoteOutput(){
$file = fopen("https://www.remote_server.com/files/the.php?param1=12","r");
$output = fread($file,1024);
fclose($file);
return $output;
}
When I call this function fopen() returns a valid handle, but fread() returns an empty string.
I have tried using file_get_contents() instead, but get the same result.
Is what I am trying to do possible?
Is it possible for the remote server to allow me to read the file via the browser, but block access from a php file?
Your variable $output is only holding the 1st 1024 bytes of the url... (headers maybe?).
You will need to add a while not the "end of file" loop to concatenate the entire remote file.
PHP reference: feof
You can learn a lot more in the PHP description for the fread function.
PHP reference: fread.
<?php
echo getRemoteOutput();
function getRemoteOutput(){
$file = fopen("http://php.net/manual/en/function.fread.php","r");
$output = "";
while (!feof($file)){ // while not the End Of File
$output.= fread($file,1024); //reads 1024 bytes at a time and appends to the variable as a string.
}
return $output;
fclose($file);
}
?>
In regards to your questions:
Is what I am trying to do possible?
Yes this is possible.
Is it possible for the remote server to allow me to read the file via
the browser, but block access from a php file?
I doubt it.
I contacted the support team for the site I was trying to connect to. They told me that they do prevent access from php files.
So that seems to be the reason for my problems, and apparently I just cannot do what I tried to do.
For what it's worth, here is the code I used to test the various methods to read file output:
<?php
//$remotefile = 'http://www.xencomsoftware.net/configurator/tracker/ip.php';
$remotefile = "http://php.net/manual/en/function.fread.php";
function getList1(){
global $remotefile;
$output = file_get_contents($remotefile);
return htmlentities($output);
}
function getList2(){
global $remotefile;
$file = fopen($remotefile,"r");
$output = "";
while (!feof($file)){ // while not the End Of File
$output.= fread($file,1024); //reads 1024 bytes at a time and appends to the variable as a string.
}
fclose($file);
return htmlentities($output);
}
function getList3(){
global $remotefile;
$ch = curl_init(); // create curl resource
curl_setopt($ch, CURLOPT_URL, $remotefile); // set url
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //return the transfer as a string
$output = curl_exec($ch); // $output contains the output string
curl_close($ch); // close curl resource to free up system resources
return htmlentities($output);
}
function getList4(){
global $remotefile;
$r = new HttpRequest($remotefile, HttpRequest::METH_GET);
try {
$r->send();
if ($r->getResponseCode() == 200) {
$output = $r->getResponseBody();
}
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
return htmlentities($output);
}
function dumpList($ix, $list){
$len = strlen($list);
echo "<p><b>--- getList$ix() ---</b></p>";
echo "<div>Length: $len</div>";
for ($i = 0 ; $i < 10 ; $i++) {
echo "$i: $list[$i] <br>";
}
// echo "<p>$list</p>";
}
dumpList(1, getList1()); // doesn't work! You cannot include/requre a remote file.
dumpList(2, getList2());
dumpList(3, getList3());
dumpList(4, getList4());
?>
Related
Hi I want to download some 250 files from a URL which are in a sequence. I am almost done with it! Just the Problem is the structure of my URL is:
http://lee.kias.re.kr/~newton/sann/out/201409//SEQUENCE1.prsa
Where id is in a sequence but the file name "SEQUENCE1.psra" has a format "SEQUENCE?.psra".
Is there any way I can specify this format of file in my code? And also there are other files in folder, but only 1 with ".psra" ext.
Code:
<?php
// Source URL pattern
//$sourceURLOriginal = "http://www.somewebsite.com/document{x}.pdf";
$sourceURLOriginal = " http://lee.kias.re.kr/~newton/sann/out/201409/{x}/**SEQUENCE?.prsa**";
// Destination folder
$destinationFolder = "C:\\Users\\hp\\Downloads\\SOP\\ppi\\RSAdata";
// Destination file name pattern
$destinationFileNameOriginal = "doc{x}.txt";
// Start number
$start = 7043;
// End number
$end = 7045;
$n=1;
// From start to end
for ($i=$start; $i<=$end; $i++) {
// Replace source URL parameter with number
$sourceURL = str_replace("{x}", $i, $sourceURLOriginal);
// Destination file name
$destinationFile = $destinationFolder . "\\" .
str_replace("{x}", $i, $destinationFileNameOriginal);
// Read from URL, write to file
file_put_contents($destinationFile,
file_get_contents($sourceURL)
);
// Output progress
echo "File #$i complete\n";
}
?>
Its working if I directly specify the URL!
Error:
Warning: file_get_contents( http://lee.kias.re.kr/~newton/sann/out/201409/7043/SEQUENCE?.prsa): failed to open stream: Invalid argument in C:\xampp\htdocs\SOP\download.php on line 37
File #7043 complete
Its making the files but they are empty!
If there is a way in which I can download that whole folder(named with id in sequence) can also work! But how do we download the whole folder in a folder?
It may be possible file_get_contents() function is not working on your server.
Try this code :
function url_get_contents ($Url) {
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
Here you go.
I didnt test the whole file_get_contents, file_put_contents part, but if you say its adding the files (albeit, blank) then I assume it still works here...
Everything else works fine. I left a var_dump() in so you can see what the return looks like.
I did what I suggested in my comment. Open the folder, parse the file list, grab the filename you need.
Also, I dont know if you read my original comments, but $sourceURLOriginal has an extra space at the beginning, which might have been giving you an issue.
<?php
$start=7043;
$end=7045;
$sourceURLOriginal="http://lee.kias.re.kr/~newton/sann/out/201409/";
$destinationFolder='C:\Users\hp\Downloads\SOP\ppi\RSAdata';
for ($i=$start; $i<=$end; $i++) {
$contents=file_get_contents($sourceURLOriginal.$i);
preg_match_All("|href=[\"'](.*?)[\"']|",$contents,$hrefs);
$file_list=array();
if (empty($hrefs[1])) continue;
unset($hrefs[1][0],$hrefs[1][1],$hrefs[1][2],$hrefs[1][3],$hrefs[1][4]);
$file_list=array_values($hrefs[1]);
var_dump($file_list);
foreach ($file_list as $index=>$file) {
if (strpos($file,'prsa')!==false) {
$needed_file=$index;
break;
}
}
file_put_contents($destinationFolder.'\doc'.$i.'.txt',
file_get_contents($sourceURLOriginal.$i.'/'.$file_list[$needed_file])
);
}
I have this code
<?php
if (!file_exists($folderAddress . $_GET['name'] . '.json')) {
//create file
$myJson = fopen($folder.$_GET['name']. ".json", "w");
//get a context of a url
$ch = curl_init($myUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$text = '';
if( ($text = curl_exec($ch) ) === false)
{
die('fail');
}
// Close handle
curl_close($ch);
//copy to json file
$result = fwrite($myJson, $text);
fclose($myJson);
$t = time();
//add update date to db
if (!mysqli_query($con, "INSERT INTO test (name )
VALUES ('$_GET['name]', '$t')")
) {
echo $text;
mysqli_close($con);
die('');
}
//show the json file
echo $text;
}
?>
And i have this problem if users request this file in same time or with less than a 500 ms delay all of them think that the file does not exist. So how can i prevent users to write file when the first is writing on it ?
You use exclusive lock when writing to a file, so the other processes can't interfere until initial one is complete. You also don't need fopen / fwrite whatsoever.
Fetch your data using cURL and use the following snippet:
file_put_contents($filename, $contents, LOCK_EX);
I have a php code which will ssh to a remote machine and execute a shell script to get list of folders. The remote machine contain more than 300 folders in the specified path in the shell script.Shell script executes well and return the list of all folders.But while I retrieve this output in php, I'am getting only around 150, 200 number of folders.
Here is my php code,
<?php
if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist");
if(!($con = ssh2_connect("ip.add.re.ss", "port")))
{
echo "fail: unable to establish connection";
}
else
{
if(!ssh2_auth_password($con, "username", "password"))
{
echo "fail: unable to authenticate";
}
else
{
$stream = ssh2_exec($con, "/usr/local/listdomain/listproject.sh");
stream_set_blocking($stream, true);
$item = fread($stream,4096);
$items = explode(" ", $item);
print_r($items);
}
}
?>
And this is my shell script.
#!/bin/bash
var=$(ls /home);
echo $var;
What is the issue with php here. Is there any limit in array size in php while getting data dynamically like here.Please advise as I am very beginner to PHP.
Thanks.
You're only reading one block of 4096 characters from your stream. if your folder list is longer than this you'll lose the rest. You need something like this:
stream_set_blocking($stream, true);
$item = "";
// continue reading while there's more data
while ($input = fread($stream,4096)) {
$item .= $input;
}
$items = explode(" ", $item);
print_r($items);
You asked fread() to only read 4096 bytes. In the examples portion of fread()’s documentation, it is suggested that stream_get_contents() be used for reading a file handle out to its end. Otherwise, you have to use a loop and keep on reading data until feof($stream) returns FALSE.
I have an issue I can't seem to find the solution for. I am trying to write to a flat text file. I have echoed all variables out on the screen, verified permissions for the user (www-data) and just for grins set everything in the whole folder to 777 - all to no avail. Worst part is I can call on the same function from another file and it writes. I can't see to find the common thread here.....
function ReplaceAreaInFile($AreaStart, $AreaEnd, $File, $ReplaceWith){
$FileContents = GetFileAsString($File);
$Section = GetAreaFromFile($AreaStart, $AreaEnd, $FileContents, TRUE);
if(isset($Section)){
$SectionTop = $AreaStart."\n";
$SectionTop .= $ReplaceWith;
$NewContents = str_replace($Section, $SectionTop, $FileContents);
if (!$Handle = fopen($File, 'w')) {
return "Cannot open file ($File)";
exit;
}/*
if(!flock($Handle, LOCK_EX | LOCK_NB)) {
echo 'Unable to obtain file lock';
exit(-1);
}*/
if (fwrite($Handle, $NewContents) === FALSE) {
return "Cannot write to file ($File)";
exit;
}else{
return $NewContents;
}
}else{
return "<p align=\"center\">There was an issue saving your settings. Please try again. If the issue persists contact your provider.</p>";
}
}
Try with...
$Handle = fopen($File, 'w');
if ($Handle === false) {
die("Cannot open file ($File)");
}
$written = fwrite($Handle, $NewContents);
if ($written === false) {
die("Invalid arguments - could not write to file ($File)");
}
if ((strlen($NewContents) > 0) && ($written < strlen($NewContents))) {
die("There was a problem writing to $File - $written chars written");
}
fclose($Handle);
echo "Wrote $written bytes to $File\n"; // or log to a file
return $NewContents;
and also check for any problems in the error log. There should be something, assuming you've enabled error logging.
You need to check for number of characters written since in PHP fwrite behaves like this:
After having problems with fwrite() returning 0 in cases where one
would fully expect a return value of false, I took a look at the
source code for php's fwrite() itself. The function will only return
false if you pass in invalid arguments. Any other error, just as a
broken pipe or closed connection, will result in a return value of
less than strlen($string), in most cases 0.
Also, note that you might be writing to a file, but to a different file that you're expecting to write. Absolute paths might help with tracking this.
The final solution I ended up using for this:
function ReplaceAreaInFile($AreaStart, $AreaEnd, $File, $ReplaceWith){
$FileContents = GetFileAsString($File);
$Section = GetAreaFromFile($AreaStart, $AreaEnd, $FileContents, TRUE);
if(isset($Section)){
$SectionTop = $AreaStart."\n";
$SectionTop .= $ReplaceWith;
$NewContents = str_replace($Section, $SectionTop, $FileContents);
return $NewContents;
}else{
return "<p align=\"center\">There was an issue saving your settings.</p>";
}
}
function WriteNewConfigToFile($File2WriteName, $ContentsForFile){
file_put_contents($File2WriteName, $ContentsForFile, LOCK_EX);
}
I did end up using absolute file paths and had to check the permissions on the files. I had to make sure the www-data user in Apache was able to write to the files and was also the user running the script.
I'm trying to get the contents of a PHP file after it is parsed, and then store it in a variable.
I couldn't get any useful information via Google, except for this one example:
ob_start();
include $file;
$content = ob_get_clean();
But this returns the contents as plain text, i.e.: The <?php and ?> tags are still there, and all code between the tags isn't parsed.
So I wanted to know, how can I do this properly?
update:
This is content of the file which is being included:
Testcontent
<?php echo 'This should be parsed, right?'; ?>
I was using this function several years ago for a sort of a template engine, it seems to do what you need - pass a string with some PHP code inside and it will return it with PHP executed. Surprisingly, it still works :-)
function process_php( $str )
{
$php_start = 0;
$tag = '<?php';
$endtag = '?>';
while(is_long($php_start = strpos($str, $tag, $php_start)))
{
$start_pos = $php_start + strlen($tag);
$end_pos = strpos($str, $endtag, $start_pos); //the 3rd param is to start searching from the starting tag - not to mix the ending tag of the 1st block if we want for the 2nd
if (!$end_pos) { echo "template: php code has no ending tag!", exit; }
$php_end = $end_pos + strlen($endtag);
$php_code = substr($str, $start_pos, $end_pos - $start_pos);
if( strtolower(substr($php_code, 0, 3)) == 'php' )
$php_code = substr($php_code, 3);
// before php code
$part1 = substr($str, 0, $php_start);
// here set the php output
ob_start();
eval($php_code);
$output = ob_get_contents();
ob_end_clean();
// after php code
$part2 = substr($str, $php_end, strlen($str));
$str = $part1 . $output . $part2;
}
return $str;
}
Based on Tyil's last comment he wants to entirety of the php file within a variable:
Tyil, what if my include file looks like this: <?php echo 'test stuff'; $foo = 'one';. What does $content contain and what happens if I try to access $foo from the including file?
#MikeB $content contains the string <?php echo 'test stuff'; $foo = 'one';. var_dump($foo); in the including file returns NULL.
<?php
$file = 'include.php';
$content = file_get_contents($file);
var_dump($content); // (string) "<?php echo 'This should be parsed, right?'; $foo = 'one'; ?>"
include.php:
<?php echo 'This should be parsed, right?'; $foo = 'one'; ?>
If you can modify your $file, than use return in it.
Otherwise cURL it (opens a web page like browser does).
This should definitely work. And it does for me:
[ghoti#pc ~/tmp]$ cat file1.php
#!/usr/local/bin/php
<?php
$file="file2.php";
include($file);
[ghoti#pc ~/tmp]$ cat file2.php
<?php echo "This should be parsed, right?\n"; ?>
[ghoti#pc ~/tmp]$ ./file1.php
This should be parsed, right?
[ghoti#pc ~/tmp]$
You might want to look at your included file (named in $file) and see if there is perhaps some strange character after the initial <?php that might cause it not to be interpreted as a PHP script.
To see a hex dump of what's in the file (so you can see what character actually follows <?php rather than what's displayed in your editor), use: od -c filename.php | less.
To do this, you have to use cURL.
Well, if you want to do it effectively, anyhow.
I know I'm several years late, but I was also looking for a solution to this issue, and I'd like to share the solution. Keep in mind, while this script does indeed get a PHP HTML page parsed, downloading via the web protocol is very slow, at least in my tests.
function GetHTMLPage($url)
{
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
...don't thank me. Thank David Walsh. (https://davidwalsh.name/curl-download)