Requiring an html page but not echoing it - php

I'm working with json and AJAX in order to get some HTML without refreshing the page. The AJAX call call a function that simplified is like this:
function postHTML($post) { // returns the HTML structure for a post starting from an array of variables
# other stuff
require('post.template.php'); // which is mostly HTML with just few php variables embedded
}
$data = '';
foreach ($posts as $post) {
$data .= postHTML($post);
}
After this I manage the json as follows:
echo json_encode(array('success' => true, 'data' => $data));
Where data should be the HTML structure of each post loaded.
The problem is that when i require the 'post.template.php' file it uses require and it returns the data to Javascript as:
[HTML posts] {"success": true, "data": ""}
How can I get the HTML into a variable and then pass it to json_encode without actually requiring the page (that should still be executed as PHP)?

You can use Output buffering, arround your require, to capture the output, preventing it from being echoed : it'll get stored in memory, and you'll be able to fetch it to a variable.
Basically, this would mean using the following kind of code :
ob_start();
// Output is no longer sent to the standard output,
// but stored in memory
require('post.template.php');
// Fetch the content that has been stored in memory
$content = ob_get_clean();
As a couple of references :
ob_start()
ob_get_clean()

<?php
function postHTML($post) { // returns the HTML structure for a post starting from an array of variables
ob_start();
# other stuff
require('post.template.php'); // which is mostly HTML with just few php variables embedded
$output = ob_get_contents();
ob_end_clean();
return $output;
}
$data = '';
foreach ($posts as $post) {
$data .= postHTML($post);
}

Put all of the data-generating code in another function and call it when necessary. (Yes nested functions are allowed in PHP, but not sure this works in your case since you're using 'require')

Related

PHP methods outputting HTML with incorrect structure?

I have a strange situation that I've never encountered where the returned HTML from my class methods doesn't output in the correct structure. For some unknown reason, everything is nested inside the HTML within the first loop, second loop, etc.
index.php
<body>
some html...
<div class="usb-port-container">
<?= $generate->output('short_name',id,'hostname'); ?>
</div>
some html...
<div class="usb-port-container">
<?= $generate->output('short_name',id,'hostname'); ?>
</div>
some html...
</body>
class.generate.php
function __construct() {
$this->getCopy = new getCopyData();
$this->getDrive = new getDriveData();
$this->helper = new helper();
}
function output ($short_name,$id,$hostname) {
$portCount = $this->getCopy->portCount($hostname, 'total');
for ($port = 0; $port < $portCount; ++$port) {
if ($this->getCopy->probePort($hostname,$port)) {
$default = $this->usbPortDefault($short_name,$id,$hostname,$port);
return $default;
} else {
$details = $this->usbPortDetails($short_name,$id,$hostname,$port);
return $details;
}
}
}
function usbPortDefault($short_name,$id,$hostname,$port) {
$port_details = '<div>
<div>----</div>
<div>----</div>
</div>';
return $port_details;
}
function outputRecords($hostname,$port) {
//get records data from database
$records = $this->getCopy->records($hostname,$port);
//create empty variable for HTML
$records_html = "";
foreach ($records as $key => $value) {
if ($value) {
$records_html .= '<div><span class="copy-group">' .$key. '</span><span class="copy-instance">' .$value. '</span></div>';
} else {
return '<div>Unable to get any group or instance</div>';
}
}
return $records_html;
}
function usbPortDetails($short_name,$id,$hostname,$port) {
$port_info = '';
$port_info .= 'bunch of HTML';
$port_info .= $this->outputRecords($hostname,$port);
$port_info .= 'bunch of HTML';
return $port_info;
}
My best guess as to the problem, is that there is an issue with the way I am returning the HTML or something with output buffering. I actually don't know if I need it within my class, but I've taken it out and issue is the same. I've also tried adding output buffering to index.html.
Here is a snippet of the source HTML. The first discrepancy I notice is that the <div class="server-details"></div> highlighted in blue doesn't belong there, it should be inside <div class="dc-container"></div> and adjacent to the prior <div class="server-details"></div>. After port-data-left should be port-data-right but it's nowhere to be found. I'm almost convinced at this point that there's a missing closing tag somewhere but I can't find it. It's been several years since I seriously did any development :D
EDIT: After further investigation, it appears that the final $port_info is not outputting and may be causing this problem. Is there an issue with $port_info .= $this->outputRecords($hostname,$port); being there?
Since you reuse you object instance using $generate, the constructor and destructor methods are only called once in this script.
The constructor starts a new output buffer using ob_start(), which means everything outputted by the output method will be buffered until you flush it.
The issue is, the flush only happens in the destructor, with ob_end_flush(), which is only executed once, after the last output call.
Because you echo the result of the method and start a buffer at the same time, the output must indeed be weird and some nesting / repetition occurs because the next output still adds to the buffer.
As pointed out in the comment, the easiest solution is to turn off the output buffering in the class.
You also need to clear $port_info at the beginning of the method to make this work, although it should be fine, unless $port_info is a global var?
This was probably not cleared in the initial Class in order to make it work when called several times, to concatenate the results (and buffer them, before outputting them all at once)
A good usage of buffers in the middle of a page is to redirect the output of a function to a variable.
For example, you could have a function that echoes code but you don't want it echoed.
You could then do something like:
Some HTML
<?php
ob_start();
call_to_some_function_that_normally_outputs_code();
$myvar = ob_get_clean();
?>
Rest of the HTML

Executing a PHP page after search + replacing keywords for language translation in the HTML

I am translating my website into different languages and I have over 130 pages so i want to pass my .php files through a function that will replace keywords
IE: Accessories = อุปกรณ์
Which is English to Thai.
I can get it to work using my method however... I have php (obviously) in these pages, and the output only displays the html and not executing the php
Is there a header method or something I have to pass at the start of my php pages..
here is the function I'm using to find text results and then replace them from my php files..
<?php
// lang.php
function get_lang($file)
{
// Include a language file
include 'lang_thai.php';
// Get the data from the HTML
$html = file_get_contents($file);
// Create an empty array for the language variables
$vars = array();
// Scroll through each variable
foreach($lang as $key => $value)
{
// Finds the array results in my lang_thai.php file (listed below)
$vars[$key] = $value;
}
// Finally convert the strings
$html = strtr($html, $vars);
// Return the data
echo $html;
}
?>
//This is the lang_thai.php file
<?php
$lang = array(
'Hot Items' => 'รายการสินค้า',
'Accessories' => 'อุปกรณ์'
);
?>
A lot of frameworks use a function to translate as it goes instead of replacing after the fact using .pot files. The function would look like this:
<h1><?php echo _('Hello, World') ?>!</h1>
So if it was English and not translated that function would just return the string untranslated. If it was to be translated then it would return the translated string.
If you want to continue with your route which is definitely faster to implement try this:
<?php
function translate($buffer) {
$translation = include ('lang_tai.php');
$keys = array_keys($translation);
$vals = array_values($translation);
return str_replace($keys, $vals, $buffer);
}
ob_start('translate');
// ... all of your html stuff
Your language file is:
<?php
return array(
'Hot Items' => 'รายการสินค้า',
'Accessories' => 'อุปกรณ์'
);
One cool thing is include can return values! So this is a good way to pass values from a file. Also the ob_start is an output buffer with a callback. So what happens is after you echo all of your html to the screen, right before it actually displays to the screen it passes all of that data to the translate function and we then translate all of the data!

how to turn the output of a require statement into a string in php

im working with a large team, and im making functions that return html code, and im echoing the result of those functions to get the final page. The thing is, i need some scrap of code developed by other member of the team, and i need it to be a string, but the code is available as a php file which im supposed to include or require inside my page.
Since im not writing an ht;ml page, but a function that generate that code, i need to turn the resulting html of the require statement into a string to concatenate it to the code generated by my function.
Is there any way to evaluate the require and concatenate its result to my strings?
Ive tried the function eval(), but didnt work, and read some thing about get_the_content(), but it isnt working either. I dont know if i need to import something, i think it have something to do with wordpress, and im using raw php.
thanks for all your help!!! =)
Try the ob_...() family of functions. For example:
<?php
function f(){
echo 'foo';
}
//start buffering output. now output will be sent to an internal buffer instead of to the browser.
ob_start();
//call a function that echos some stuff
f();
//save the current buffer contents to a variable
$foo = ob_get_clean();
echo 'bar';
echo $foo;
//result: barfoo
?>
If you want to put the echo'd result of an include into a variable, you could do something like this:
//untested
function get_include($file){
ob_start();
include($file);
return ob_get_clean();
}
or if you want to put the echo'd result of a function call into a variable, you could do something like this:
//untested
//signature: get_from_function(callback $function, [mixed $param1, [mixed $param2, ... ]])
function get_from_function($function){
$args = func_get_args();
shift($args);
ob_start();
call_user_func_array($function,$args);
return ob_get_clean();
}
Depending on how the other file works...
If the other file can be changed to return a value, then you should use:
$content = require 'otherfile';
If the other file simply uses echo or some other way to print directly, use:
ob_start();
require 'otherfile';
$content = ob_get_clean();
You can receive string with include or require but you have to update those files before including to add return statement.
the file to be included should return result like this
<?php
$var = 'PHP';
return $var;
?>
and you can receive the $var data by including that file
$foo = include 'file.php';
echo $foo; // will print PHP
Documentation section

Include a file into a variable

I am trying to keep my code clean break up some of it into files (kind of like libraries). But some of those files are going to need to run PHP.
So what I want to do is something like:
$include = include("file/path/include.php");
$array[] = array(key => $include);
include("template.php");
Than in template.php I would have:
foreach($array as $a){
echo $a['key'];
}
So I want to store what happens after the php runs in a variable to pass on later.
Using file_get_contents doesn't run the php it stores it as a string so are there any options for this or am I out of luck?
UPDATE:
So like:
function CreateOutput($filename) {
if(is_file($filename)){
file_get_contents($filename);
}
return $output;
}
Or did you mean create a function for each file?
It seems you need to use Output Buffering Control -- see especially the ob_start() and ob_get_clean() functions.
Using output buffering will allow you to redirect standard output to memory, instead of sending it to the browser.
Here's a quick example :
// Activate output buffering => all that's echoed after goes to memory
ob_start();
// do some echoing -- that will go to the buffer
echo "hello %MARKER% !!!";
// get what was echoed to memory, and disables output buffering
$str = ob_get_clean();
// $str now contains what whas previously echoed
// you can work on $str
$new_str = str_replace('%MARKER%', 'World', $str);
// echo to the standard output (browser)
echo $new_str;
And the output you'll get is :
hello World !!!
How does your file/path/include.php look like?
You would have to call file_get_contents over http to get the output of it, e.g.
$str = file_get_contents('http://server.tld/file/path/include.php');
It would be better to modify your file to output some text via a function:
<?php
function CreateOutput() {
// ...
return $output;
}
?>
Than after including it, call the function to get the output.
include("file/path/include.php");
$array[] = array(key => CreateOutput());

php print whole page

Quite simple question i belive. How to print the whole page into variable and then use where i need.
For instance if the code is:
<?php
$arr = array('hello','mate','world');
foreach ($arr as $a) {print "<p>".$a."</p>"; }
?>
Now if we go to that page, we can see an array output, but i would prefer to print the whole page into variable and then generate static page for instance out of that.
Maybe file_get_content or <<<EOT, but the page will get more complicated later so not sure what is the best option.
Not sure about your exact needs but:
ob_start();
require('/path/to/templates/foo.php');
$template = ob_get_contents();
ob_get_clean();
ob_start();
// your code
$var = ob_get_clean();
print $var;
Why don't you use smarty ,
put all HTML in a template , and insert PHP code or variables into it . in the end , using $x=$smarty->fetch('template_name'); you put all the page in the $x variable ...

Categories