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)
Related
I have a php page that outputs html to the browser based on a query string that is parsed. The issue I am having is that I need to retrieve this html source code dynamically via php.
The following code will not work because it tries to resolve an absolute path as it's on the same server:
$url = 'http://example.com/myScript.php';
$html = file_get_contents($url);
If I manually set the absolute path it just returns the php contents as text (not executed like a browser would do):
$url = '/dir1/dir2/dir3/dir4/myScript.php';
$html = file_get_contents($url);
I then researched it and found that using ob_get_contents could work. The code below works as expected, executing the script and returning the html output.
$url = '/dir1/dir2/dir3/dir4/myScript.php';
ob_start();
include($url);
$html = ob_get_contents();
ob_end_clean();
The problem with the above solution is that as soon as I put the query string on the end it fails. I think this is because it's treating the query string as part of the file name.
Use PHPs ob_get_contents
<?php
ob_start();
$original_get = $_GET;
$_GET = ["query" => "tags", "you" => "need", "in" => "file.php"];
$file = "file.php";
include($file);
$_GET = $original_get;
$content = ob_get_contents();
ob_clean();
echo $content;
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());
?>
i searched Google but found nothing what fits for my problem, or i search with the wrong words.
In many threads i read, the smarty Template was the solution, but i dont wont use smarty because its to big for this little project.
My problem:
I got a CSV file, this file contents only HTML and PHP code, its a simple html template document the phpcode i use for generating dynamic imagelinks for example.
I want to read in this file (that works) but how can i handle the phpcode inside this file, because the phpcode shown up as they are. All variables i use in the CSV file still works and right.
Short Version
how to handle, print or echo phpcode in a CSV file.
thanks a lot,
and sorry for my Bad english
Formatting your comment above you have the following code:
$userdatei = fopen("selltemplate/template.txt","r");
while(!feof($userdatei)) {
$zeile = fgets($userdatei);
echo $zeile;
}
fclose($userdatei);
// so i read in the csv file and the content of csv file one line:
// src="<?php echo $bild1; ?>" ></a>
This is assuming $bild1 is defined somewhere else, but try using these functions in your while loop to parse and output your html/php:
$userdatei = fopen("selltemplate/template.txt","r");
while(!feof($userdatei)) {
$zeile = fgets($userdatei);
outputResults($zeile);
}
fclose($userdatei);
//-- $delims contains the delimiters for your $string. For example, you could use <?php and ?> instead of <?php and ?>
function parseString($string, $delims) {
$result = array();
//-- init delimiter vars
if (empty($delims)) {
$delims = array('<?php', '?>');
}
$start = $delims[0];
$end = $delims[1];
//-- where our delimiters start/end
$php_start = strpos($string, $start);
$php_end = strpos($string, $end) + strlen($end);
//-- where our php CODE starts/ends
$php_code_start = $php_start + strlen($start);
$php_code_end = strpos($string, $end);
//-- the non-php content before/after the php delimiters
$pre = substr($string, 0, $php_start);
$post = substr($string, $php_end);
$code_end = $php_code_end - $php_code_start;
$code = substr($string, $php_code_start, $code_end);
$result['pre'] = $pre;
$result['post'] = $post;
$result['code'] = $code;
return $result;
}
function outputResults($string) {
$result = parseString($string);
print $result['pre'];
eval($result['code']);
print $result['post'];
}
Having PHP code inside a CSV file that should be parsed and probably executed using eval sounds pretty dangerous to me.
If I get you right you just want to have dynamic parameters in your CSV file right? If thats the case and you don't want to implement an entire templating language ( like Mustache, Twig or Smarty ) into your application you could do a simple search and replace thing.
$string = "<img alt='{{myImageAlt}}' src='{{myImage}}' />";
$parameters = [
'myImageAlt' => 'company logo',
'myImage' => 'assets/images/logo.png'
];
foreach( $parameters as $key => $value )
{
$string = str_replace( '{{'.$key.'}}', $value, $string );
}
Below is my working code that pulls a text file from a remote location and inserts into the html body of a page a specific line. The code works just fine as it is now. I want to do an addition to the code however and have it randomize the line that it gets. Here is what I'm wanting to do.
The text file that is being pulled will have a varied amount of lines. Only one line is chosen via the echo $lines[0]; which tells which line to get. The line will be formatted like this..
<p>This is a line of text domain 1. This is a line of text.</p><p>This is a line of text domain 2. This is a line of text.</p><p>This is a line of text domain 3. This is a line of text.</p>
All of that would be one line and pulled into the html of the page. The above example would display 3 paragraphs of text with links in the order above.
What I would like to do is have that line of text randomize between the <p>..</p> So for instance if I put the below code on Site A the output would be in order of domain 1 then domain 2 and then domain 3. If I put the code on Site B I would like it to be domain 3 and then domain 1 and then domain 2. To display them in random order, not the exact order for each time I put the code on a site.
I don't know if there would need to be some sort of cache on the site I have the code on to remember which random order to display in. That is what I want. I do not want a random order on each page load.
I hope this makes sense. If not please tell me so I can try and explain it better. Here is my working code as of now. Can anyone help me get this working? Thank you very much for your help.
<?php
function url_get_contents ($url) {
if (function_exists('curl_exec')){
$conn = curl_init($url);
curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($conn, CURLOPT_FRESH_CONNECT, true);
curl_setopt($conn, CURLOPT_RETURNTRANSFER, 1);
$url_get_contents_data = (curl_exec($conn));
curl_close($conn);
}elseif(function_exists('file_get_contents')){
$url_get_contents_data = file_get_contents($url);
}elseif(function_exists('fopen') && function_exists('stream_get_contents')){
$handle = fopen ($url, "r");
$url_get_contents_data = stream_get_contents($handle);
}else{
$url_get_contents_data = false;
}
return $url_get_contents_data;
}
?>
<?php
$data = url_get_contents("http://mydomain.com/mytextfile.txt");
if($data){
$lines = explode("\n", $data);
echo $lines[0];
}
?>
Try This
$str = '<p>This is a line of text domain 1. This is a line of text.</p><p>This is a line of text domain 2. This is a line of text.</p><p>This is a line of text domain 3. This is a line of text.</p>';
preg_match_all('%(<p[^>]*>.*?</p>)%i', $str, $match);
$count = 0;
$used = array();
while ($count < 3) {
$index = rand(0, 2);
if (!isset($used[$index])) {
$used[$index] = 1;
echo $match[0][$index];
$count++;
}
}
I think I understand what you are asking, but if not, please let me know and I will adjust.
Basically, what I'm doing here is counting the number of lines in the array that you exploded and then using that as a max number to randomize against. Once I have a random number, then I just access that line of the file array. So if I generate the number 5, then it will grab the 5th line from the array.
$lines = explode("\n", $data);
$line_count = count($lines) - 1;
for ($i = 0; $i < 3; $i++) {
print "<p>".$lines[get_random_line($line_count)]."</p>";
}
function get_random_line($line_count) {
mt_srand(microtime() * 1000000);
$random_number = rand(0, $line_count);
return $random_number;
}
Without modifying your code too much and without getting into storing values in databases, using flat file storage you can do something like the following:
Create a file called "count.txt" and place it in the same location as your php file.
<?php
function url_get_contents ($url) {
if (function_exists('curl_exec')){
$conn = curl_init($url);
curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($conn, CURLOPT_FRESH_CONNECT, true);
curl_setopt($conn, CURLOPT_RETURNTRANSFER, 1);
$url_get_contents_data = (curl_exec($conn));
curl_close($conn);
}elseif(function_exists('file_get_contents')){
$url_get_contents_data = file_get_contents($url);
}elseif(function_exists('fopen') && function_exists('stream_get_contents')){
$handle = fopen ($url, "r");
$url_get_contents_data = stream_get_contents($handle);
}else{
$url_get_contents_data = false;
}
return $url_get_contents_data;
}
$data = url_get_contents("http://mydomain.com/mytextfile.txt");
$fp=fopen('count.txt','r');//Open count.txt for reading
$count=fread($fp,4) ? $count++ : $count=0;//Get and increment $count (4=no. bytes to read)
fclose($fp); //Close file
if($data){
$lines=explode("\n",$data);
if($count>count($lines)){$count=0;}//Reset $count if more than available lines
echo $lines[$count];
$fp=fopen('count.txt','w'); //Another fopen to truncate the file simply
fwrite($fp,$count); //Store $count just displayed
fclose($fp); //Close file
}
?>
Sounds like your really looking for a way to have unique content or maybe also have the appearance to updated content on your HTML page. This has been extremely useful for me and Im sure many others will like it as well even though it is a bit different than what you are trying to do.
This will grab nested Spintax from a text file. It will then spin the content and display in your page. Your page will need to be .php however there is a way for this to work on an HTML page that's what I use this for.
Spintax Example: {cat|Dog|Mouse} Works on Sentence Spins, Spin/Rotate images, spin HTML code etc... There are many things that you can do with this.
<?php
function spin($s){
preg_match('#\{(.+?)\}#is',$s,$m);
if(empty($m)) return $s;
$t = $m[1];
if(strpos($t,'{')!==false){
$t = substr($t, strrpos($t,'{') + 1);
}
$parts = explode("|", $t);
$s = preg_replace("+\{".preg_quote($t)."\}+is",
$parts[array_rand($parts)], $s, 1);
return spin($s);
}
$file = "http://www.yourwebsite/Data.txt";
$f = fopen($file, "r");
while ( $line = fgets($f, 1000) ) {
echo spin($line);
}
?>
I'm struggling trying to read a php file inside a php and do some manipulation..after that have the content as a string, but when I try to output that with echo or print all the php tags are literally included on the file.
so here is my code:
function compilePage($page,$path){
$contents = array();
$menu = getMenuFor($page);
$file = file_get_contents($path);
array_push($contents,$menu);
array_push($contents,$file);
return implode("\n",$contents);
}
and this will return a string like
<div id="content>
<h2>Here is my title</h2>
<p><? echo "my body text"; ?></p>
</div>
but this will print exactly the content above not compiling the php on it.
So, how can I render this "compilePage" making sure it returns a compiled php result and not just a plain text?
Thanks in advance
function compilePage($page, $path) {
$contents = getMenuFor($page);
ob_start();
include $path;
$contents .= "\n".ob_get_clean();
return $contents;
}
To evaluate PHP code in a string you use the eval function, but this comes highly unadvised. If you have a file containing PHP code, you can evaluate it with include, include_once, require, or require_once depending on your need. To capture the output of an included file - or required, or whichever method - you need to enable output buffering.
You can use output buffering for this, and include the file normally:
function compilePage($page,$path){
$contents = array();
$menu = getMenuFor($page);
ob_start();
include $path;
$file = ob_get_contents();
ob_end_clean();
array_push($contents,$menu);
array_push($contents,$file);
return implode("\n",$contents);
}
The include() call will include the PHP file normally, and <?php blocks will be parsed and executed. Any output will be captured by the buffer created with ob_start(), and you can get it later with the other ob_* functions.
You need to use include() so it will execute. You can couple this with output buffering to get the return in a string.
function compilePage($page,$path){
$contents = array();
$menu = getMenuFor($page);
//output buffer
ob_start();
include($path);
$file = ob_get_contents();
ob_end_clean();
array_push($contents,$menu);
array_push($contents,$file);
return implode("\n",$contents);
}