Using print_r in ob_start - php

As mentioned in the manual it's not working. i tried var_dump it too suffers from the same problem.
ob_start()
$debugdata=print_r ($var,true)
This prints the result on screen than storing to a variable

The second parameter of print_r is $return which allows the output to be returned as a string rather than outputting it:
$debugData = print_r($var, true);
There is no need to use output buffering for this, and in fact it cannot be used. You will need to end the output buffering before this and then restart the buffering after your print_r call:
ob_start();
// stuff
$output = ob_end_clean();
$debugData = print_r($var, true);
ob_start();
// more stuff
$output .= ob_end_clean();
EDIT: Another option is to nest output buffers and have an inner buffer do the print_r work:
ob_start(); // your original start
// stuff
ob_start();
print_r($var);
$debugData = ob_get_clean();
// more stuff
$output = ob_get_clean(); // your original end

ob_start() starts outbut buffering. But you also need to end and retrieve the contents of the buffer as well.
Here are the functions you could use:
ob_get_clean() - puts the contents of the output buffer in a variable, ends and cleans the buffer.
ob_start();
print_r($foo);
$output = ob_get_clean();
ob_get_contents() - fetches the contents of the output buffer without closing or cleaning it.
ob_end_clean() - closes and cleans the buffer.
ob_start();
print_r($foo);
$output = ob_get_contents();
ob_end_clean();
There are a few other possibilities. Please make yourself familiar with the output buffering functions.
Also, a remark. You don't just assign the output of print_r to a variable. You just print stuff as if you were printing it on the screen. With output buffering on, all output will be buffered instead of being sent to stdout immediately. So, first you print_r, then retrieve the contents of the buffer.
[EDIT]
In the light of the conversation going on in the comments, I recommend having a look at the notes section of the print_r() manual. As #RomiHalasz and #cbuckley observe, due to print_r's internal output buffering, it cannot be used in conjunction with ob_start()
while the second parametre, return, is used, as the two will collide.
You have to EITHER use output buffering and plain print_r (with only the first parametre), or end the output buffering before you use print_r with the second parametre.
Either this:
ob_start();
print_r($foo);
$output = ob_get_clean();
or this:
ob_start();
// blah
$output = ob_get_clean();
$output .= print_r($foo,true);
ob_start();
// blah
$output .= ob_get_clean();

Related

PHP output buffer - How to access a specific level?

When I do:
print_r(ob_list_handlers());
I get:
Array ( [0] => default output handler [1] => W3TC\Generic_Plugin::ob_callback [2] => Weglot::treatPage )
It seems that every time ob_start() is called it creates a new level or a new index or something in the ob stack.
How can I access the content of a specific level instead of just the default one?
yes you are exactly right with each ob_start() you're adding one level to the stack but if you want to accumulate the outputs and later you want to use that output, i recommend using an array to put the output in. at the end of each ob_start() you need to close the buffer with ob_end_...() either you add levels to the buffer or open and close the buffer at each time so
$output = array();
ob_start();
echo("<h1>hello</h1>");
array_push($output, ob_get_contents());
ob_end_clean();
ob_start();
echo("<h3> world</h3>");
array_push($output, ob_get_contents());
ob_end_clean();
echo $output[0]." ".$output[1];
or
$output = array();
ob_start();
echo("<h1>hello</h1>");
array_push($output, ob_get_contents());
ob_start();
echo("<h3> world</h3>");
array_push($output, ob_get_contents());
ob_end_clean();
ob_end_clean();
echo $output[0]." ".$output[1];
doesn't make any difference. i hope this could help

How to return an included file in PHP without using a return

I am trying to turn an existing website in an API, in order to do that I need to return some content as HTML inside a JSON. The problem I am having is that I can't find a way to make templating work.
I tried to do this
class TestController
{
public function get() {
$adapter = new Adapter();
$data = 'some data';
$html = include $_SERVER['DOCUMENT_ROOT'] . 'template.php';
$result = [
'html' => $html
];
return json_encode($result);
}
template.php:
<div>
<br/><?= $data ?><br/>
</div>
but it is returning the HTML alongside the JSON and of course html = 1 because include returns 1 on success, like this:
<div>
<br/>some data<br/>
</div>
{'html':1}
Is there a way for me to get the content from the included file without using a return statement inside the template?
Your problem is that using include essentially treats your template.php file as a single giant "echo" because there is no value returned inside template.php
You could change the template.php file to return a HTML string, and it would achieve what you want, but this is a nightmare to look at and manage.
return '<div>
<br/>' . $data . '<br/>
</div>';
An alternative, is to "capture" the output of the included file. Its a lot nicer on your template.php file and achieves the same thing. The output buffer functions essentially capture any information "echoed" - you need to be careful using this and the placement of your session_start however as it can catch you off guard depending on how your application is bootstrapped.
This is done by using three ob_ functions the main one being ob_get_contents which will be the contents of template.php in the example below.
http://php.net/manual/en/function.ob-get-contents.php
ob_start();
include $_SERVER['DOCUMENT_ROOT'] . 'template.php';
$html = ob_get_contents();
ob_end_clean();
This was your template files stay nice and clean, and the contents are all captured for returning in your json format.
you can use ob_start like this
ob_start();
include 'path_to_your_file.php';
$result= ob_get_contents();
ob_end_clean();

var_dump has unreadable output

I have a method to dump a var_dump output to a file, as such:
function dumpToFile($object) {
$file = "c:/tmp/php.log";
ob_start();
var_dump($object);
$output = ob_get_clean();
$fh = fopen($file, "a+");
fwrite($fh, $output."\r\n");
}
Out of nowhere, the output of this is always starting with a tag like this and has some characters that are HTML encoded, like &quot
<pre class='xdebug-var-dump'> dump content... </pre>
I don't remember changing the PHP.ini file, any ideas ? I'm using php-cgi.exe under Windows.
var_dump itself outputs the garbled data, so it's not my method as far as I can see.
Seems like your xdebug has been enabled. See below post on how to disable:
https://stackoverflow.com/a/8754934

How to use ob_start on a string?

I have a project where I am using OB_START to gather output from a PHP file. The problem is that sometimes I need the contents of the PHP file 20 - 30 times in 1 call.
I'd like to do something like get_file_contents({file}) then use that string for the OB_START() call. However, all the examples I've seen use an include() call to get the script each time.
Is there a way to load the script one time but use it several times in OB_START() calls?
ob_start();
include "file.php";
$output = ob_get_clean();
What I would like to do:
$script = get_file_contents(file);
$output = '';
begin loop;
ob_start();
{somehow make $script execute as code}
$output .= ob_get_clean();
end loop;
You can just use include over-and-over again.
$file = "SomeScript.php"
$output = '';
begin loop;
ob_start();
include $file
$output .= ob_get_clean();
end loop;
If you're dead-set on doing it the way you're describing, you can do the following, but it's weird:
$script = get_file_contents(file);
$output = '';
begin loop;
ob_start();
eval($script);
$output .= ob_get_clean();
end loop;
In my opinion, a much better solution would be to make the script a function that outputs it's results instead of printing them. So let's say you put the "script" into a function call foo(), Then you could do this:
$file = "SomeScript.php"
include $file
$output = '';
begin loop;
$output .= foo();
end loop;
But if you cannot change the contents of the script, then my first two examples should work for you.

exec() and passthru() php executing

I try to execute a python script with PHP But I got no results:I tried
$tmp = passthru("C:\\Python27\\python.exe C:\\Python27\\script.py C:\\Python27\\file.pdf",$output);
print($output)
The results :"1"
While
$tmp = exec("C:\\Python27\\python.exe C:\\Python27\\script.py C:\\Python27\\file.pdf",$output);
returns Array ( )
I'm excepted to return a string,any suggestions?
I verified in my php.ini file
safe_mode = Off
Thanks!!
The documentation of exec() says that the $output parameter is an array that will be filled in with each line. If you want to turn this into a single string, use:
$output_string = implode("\n", $output);
This should work for you:
ob_start();
passthru("C:\\Python27\\python.exe C:\\Python27\\script.py C:\\Python27\\file.pdf");
$filedata = ob_get_clean();
echo $filedata;
python buffers output by default. Set environment variable PYTHONUNBUFFERED to a nonempty string, or run python with -u.

Categories