Why need use ob_start() with include()? - php

Why is recommended use ob_start() in PHP language when you need include other PHP (or template) file?
This is bad:
require_once( dirname( __DIR__ ) . '/views/file.php' );
This is good:
ob_start();
require_once( dirname( __DIR__ ) . '/views/file.php' );
$output = ob_get_clean();
return $output;
But i don't get why

There is no such recommendation, use it if you think its necessary.
ob_start() tells PHP to start buffering output, any echo or other output by any means will be buffered instead of sent straight to the client.
This can be used for many purposes, one of them is being able to send headers even after producing output, since the output wasn't sent yet thanks to buffering.
In this particular piece of code you have, you are using output buffer to catch the output generated by your included file and storing it to a variable, instead of sending it to the client.

It would be hard to say without understanding a little more about your program, as well as who is telling you to do this. For one thing, the return $output line at the bottom--what are you returning from?
I can think of many reasons you'd want to include scripts this way.
In PHP, the ob_* functions deal with output buffering, that is, capturing anything that gets printed to the page/screen your PHP code is running in as a string.
This may be necessary because a very common pattern in classic PHP is to write straight HTML outside of any <?php tags. When you output text this way, it gets sent directly to the screen, bypassing any intermediate processing that you may want to do with it. It's also possible that a programmer may want to define all of their includes in one place, so that they can be switched out easily, and then reference the text to be output as a variable later in the script.
It may also be a way to prevent includes that don't output any text from accidentally outputting white space, making it impossible to change headers later on in the script. I've had problems before with a large code base in which every include had been religiously closed with a ?> and may or may not have included white space afterward. This would have solved the problem with comparatively little effort.
In programming, there are often many different ways to do things, and there's not always one of them that's "right." The end goal is to create something that does its job, is maintainable, and can be comprehended by other programmers. If you have to write a couple of extra lines of code in pursuit of maintainability, it's worth it down the line.

ob_start() is a function that begins output buffering, ob_get_clean(); flushes the buffer, and it looks like you are returning it from a function.
This allows any print or echo statements to be added to the buffer, and then all stored to a variable and returned and printed elsewhere in your application.

Related

PHP Complete list of functions and statments that can output

Note: "output" is meant to meant to data that streams out of php; Eg, stdout, output buffer, data that is returned to an incomming web request. "Output" is not to mean, the value that a functions that returns.
Note: "function and statements" is meant to refer to anything that a php script can do; What could approximately be referred to as a callable, or a statement; Or that PHP Docs refer to as a Language Construct. Or anything else that can in some way, make php output something somewhere.
I need to locate anything that can output in a php project, a prerequisite for finding all these things is determine a list of what can output.
I suggest this is different to a similar question because that questioned asked specifically about things that output to a browser, assumedly via an Apache host. Whereas this question is intended about php-cli, or any way of running php, which may include, but does not target PHP on Apache.
I appreciate that this is an awkward question and that php is an awkward interpreter to which no absolute list can probably be derived. I'd still like to expand my knowledge of things that can output as to better beware.
echo
var_dump
printr
var_export
closing brace ?> (if opened with <?php, or '<?, or <?=)
alt closing brace </script> (if opened with <script language="php">)
alt closing brace ASP %? (if opened with <%, or <%=)
print
printf
flush
ob_flush
ob_end_flush
debug_zval_dump
debug_print_backtrace
readfile
fpassthru
phpinfo
phpcredits
highlight_string
highlight_file
some image* functions
exit, die
This list was assorted by manually navigating the "see also" sections of known php output functions. These results stand on the shoulders of thous listed on a similar question.
I tried to parse the php documentation's standalone copy but found it too sloppy to parse meaningful. Thous are available here: http://php.net/download-docs.php

Several <?php ?> blocks vs single one (semantics and functionality)

What I keep seeing is something like
<?php $page_title = ""; ?>
<?php include_once("inc/header.php"); /* Include Header */ ?>
versus
<?php
$page_title = "";
include_once("inc/header.php"); /* Include Header */
?>
I assume there is no difference in functionality (not sure however), but which way is more semantic / correct does it matter if you declare all your PHP in several PHP blocks or a single one? Is performance affected in any way?
This is a major reason why doing your PHP inline is going out of style. There's no performance hit that I know of. All <?php ?> does is tell the interpreter that this is to be processed by PHP so your first code block is saying
Stop parsing PHP
Start Parsing PHP
I would imagine there's some miniscule hit somewhere if you're trying to wring every last ounce of efficiency out but I consider it to be insignificant. It's important to userstand that if you're using opcode cache (and you should) then the only hit is on the parsing side. Repeated execution of cache will have 0 effect here.
Readability, however, really does demand your code be as compact as possible. Remember, someone may come behind you and work on this code. Having two blocks where only one is needed is inefficient.
There is no real answer to this.
Some people like to have it the "Code-Block"-Way and put it all in one set of tags, some other people prefer the "HTML-Tag"-Way where they put each command in a new set of tags
There is no difference in functionality except for the fact that everything between one ?> and the next <?php gets echo'ed (So you have a lot of spaces in your output HTML, which is okay, since they are ignored)
Performance might be affected, but in numbers you really don't need to care about.
Generally, if you are in templates (or lets say, PHTML, HTML and PHP mixed), try to keep all commands single-lined (Put all single commands in <?php ?> and on own lines), this will make it more readable between all those HTML tags.
If you don't have HTML in your PHP file, there is no reason to enclose all commands with PHP tags

How does the PHP code execute even without closing the ?> PHP tag?

Following is the code I come to notice from a PHP file:
<?php
# Should log to the same directory as this file
$log = KLogger::instance(dirname(__FILE__), KLogger::DEBUG);
$args1 = array('a' => array('b' => 'c'), 'd');
$args2 = NULL;
$log->logInfo('Info Test');
$log->logNotice('Notice Test');
$log->logWarn('Warn Test');
$log->logError('Error Test');
$log->logFatal('Fatal Test');
$log->logAlert('Alert Test');
$log->logCrit('Crit test');
$log->logEmerg('Emerg Test');
$log->logInfo('Testing passing an array or object', $args1);
$log->logWarn('Testing passing a NULL value', $args2);
You can notice that the closing PHP tag(?>) is not present there but still all the statements within code are working perfect. I'm not getting how this could be possible to execute the code without completion of PHP tag(?>). I researched but didn't get any satisfatory explanation. Can anyone guide me in this regard? Thanks in advance.
The closing tag exists to tell the interpretter that it should stop executing the text and just output it verbatim. Unlike XML, which requires openning and closing tags to match to be valid, the PHP interpretter simply uses the tags to delimit where execution should start and stop.
Just like a PHP file could have no opening tag - meaining that the entire contents would be output, no closing tag is necessary as once the end-of-file is reached execution ends.
While I can't remember any other reason, sending headers earlier than the normal course may have far reaching consequences. Below are just a few of them that happened to come to my mind at the moment:
While current PHP releases may have output buffering on, the actual production servers you will be deploying your code on are far more important than any development or testing machines. And they do not always tend to follow latest PHP trends immediately.
By sending headers inadvertently, you might have introduced a security vulnerability: say, you are doing a redirection, but hence the headers are already sent, the redirection does not work and the rest of the page might be output, thus the visitor may see what she was not supposed to see. While this can be mitigated by using exit, you know the story, only if every one of us utilize good programming habits every time.
Even if letting the visitor stay in the wrong page does not have a security implication, by breaking a session behavior, or in some other ways I've encountered over years, the security and/or session cycle might have taken some sort of blow in the end.
If not security, you may have headaches over inexplicable functionality loss. Say, you are implementing some kind payment gateway, and redirect user to a specific URL after successful confirmation by the payment processor. If some kind of PHP error, even a warning, or an excess line ending happens, the payment may remain unprocessed and the user may still seem unbilled. This is also one of the reasons why needless redirection is evil and if redirection is to be used, it must be used with caution.
You may get "Page loading canceled" type of errors in Internet Explorer, even in the most recent versions. This is because an AJAX response/json include contains something that it shouldn't contain, because of the excess line endings in some PHP files, just as I've encountered a few days ago.
If you have some file downloads in your app, they can break too, because of this. And you may not notice it, even after years, since the specific breaking habit of a download depends on the server, the browser, the type and content of the file (and possibly some other factors I don't want to bore you with).
Bonus: a few gotchas (actually currently one) related to these 2 characters:
Even some well-known libraries may contain excess line endings after ?>. An example is Smarty, even the most recent versions of both 2.* and 3.* branch have this. So, as always, watch for third party code. Bonus in bonus: A regex for deleting needless PHP endings: replace (\s*\?>\s*)$ with empty text in all files that contain PHP code.
From the PHP Manual:
The closing tag of a PHP block at the end of a file is optional, and in some cases omitting it is helpful when using include or require, so unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Output Buffer and die() / exit() function?

I hope everyone's holidays are going well.
Another PHP related question here. I am using output buffers in my script, for what I have recently learned is an invalid reason (so I can pass headers later in the script). I now realize that I should be storing all output in a variable or some other sort of storage until I am ready to output at the end of the script instead of using output buffers. Unfortunately, I have already coding these functions and the spontaneous output of html into my pages already. I was hoping to be able to fix this problem in version 2 of the script, as I have strict deadlines to meet with this version.
To the question at hand. I was planning to do this, but apparently die() and exit() functions do not work so well with output buffers? I have exit() after all of my error messages, and instead of ending the execution at that point, it seems the script keeps going due to the output buffer. I have tested this hypothesis by removing the output buffers and the exit() functions work as expected.
Is there a way I change this behaviour, or should I go back to the drawing board and begin replacing my older pages? Also, can someone please explain to me why we should keep output till the end? I'm always interested in learning.
Thanks in advance everyone! Enjoy the last few days of 2010!
While I'll leave the headier and more abstract questions to more intelligent minds than I, I would recommend that you create a wrapper exit() function to simplify the code when you have errors.
i.e-
if(!$good)
{
trigger_error('bleh', E_USER_WARNING);
errorExit();
}
function errorExit()
{
ob_flush();
exit();
}
And replace all your exits with that function call and that way the buffer is flushed and the program will exit at the proper time.
Difference between header and the actual page content is basically only the position where they occur.
As the name suggests, header is in the beginning of the output. After that two carriage/returns (enter symbols) are sent and everything after that is presumed to be content.
Therefore, if you echo something and then want to change the header, it cannot be done. The content part already closed header part. What you would send as new header would now display as plain text (should PHP interpreter not stop you, which it does).
As for the other part of the question, ob_flush is a good solution as noted by Patrick.

'echo' or drop out of 'programming' write HTML then start PHP code again

For the most part, when I want to display some HTML code to be actually rendered I would use a 'close PHP' tag, write the HTML, then open the PHP again. eg
<?php
// some php code
?>
<p>HTML that I want displayed</p>
<?php
// more php code
?>
But I have seen lots of people who would just use echo instead, so they would have done the above something like
<?php
// some php code
echo("<p>HTML that I want displayed</p>");
// more php code
?>
Is their any performance hit for dropping out and back in like that? I would assume not as the PHP engine would have to process the entire file either way.
What about when you use the echo function in the way that dose not look like a function, eg
echo "<p>HTML that I want displayed</p>"
I would hope that this is purely a matter of taste, but I would like to know if I was missing out on something. I personally find the first way preferable (dropping out of PHP then back in) as it helps draw a clear distinction between PHP and HTML and also lets you make use of code highlighting and hinting for your HTML, which is always handy.
The first type is preferable, exactly for the reasons you mentioned.
Actually, echoing out whole chunks of html is considered bad practice.
No, there's no performance increase that would be visible.
Sometimes its just simply easier to output content using echo (for example, when inside a while or for loop) than to close the php tag.
I think there's a preprocessor which converts the same form into the second. That's what happens in ASP.NET, anyway. And in both ASP.NET and classic ASP, loops can actually stretch across raw-HTML regions.
There's no performance difference at all.
Just the style that produces the most readable code. Depending on the actual situation that can be either of the two.
But mixing HTML and PHP should be avoided where possible anyway. THis can be accomplished by using a template system for your views.

Categories