PHP output buffer stacking - php

The following is not achieving what I desire
<?
echo ob_start() . "<br>";
echo "1x<br>";
echo ob_start() . "<br>";
echo "2x<br>";
echo ob_flush() . "<br>";
echo "3x<br>";
echo ob_flush() . "<br>";
?>
The output is the following
1
1x
1
2x
1
3x
1
I am wanting something along the lines of
1x
3x
2x
I assume the problem is its putting the output from the second ob_start() in the first output buffer. But how do I get my desired output?
Basically what I am trying to achieve is providing the tag which needs to be in the head of a HTML document at a latter point in the output. Ie, half way through the script after it has already printed the docs head infomation it needs to then provide the .

Refer to the PHP manual for ob_start. You don't want to
echo ob_start();
because that function returns true or false, so it will output a 1 or 0
instead
ob_start();
echo "1x" . "<br />";
echo "2x" . "<br />";
echo "3x" . "<br />";
ob_flush();
Overall your objective isn't very clear. ob_start() is used for cleaning up a bunch of output before it is sent. It shouldn't be used as a stack.
Try SplStack if you want to use a stack in PHP.

Why don't you just write
echo "1x"."<br>";
echo "3x"."<br>";
echo "2x"."<br>";

What about the following:
<?php
echo ob_start();
echo "1x<br>";
$keep_me_1 = ob_get_contents(); /* optional and for later use */
echo ob_flush();
echo ob_start();
echo "3x<br>";
$keep_me_2 = ob_get_contents(); /* optional and for later use */
echo ob_flush();
echo ob_start();
echo "3x<br>";
$keep_me_3 = ob_get_contents(); /* optional and for later use */
echo ob_flush();
?>
If you want to use more of the "stack" functionality you should take a look at ob_end_flush.

You can use ob_get_contents() to save the contents of the inner buffer to a string, then call ob_end_clean() to throw the contents away. Later, use a callback function in the outer buffer to write out the string.

Your issue is that ob_* functions should not be echo'ed.
<?
ob_start() . "<br>";
echo "1x<br>";
ob_start() . "<br>";
echo "2x<br>";
ob_flush() . "<br>";
echo "3x<br>";
ob_flush() . "<br>";
?>
ob_start() function returns a boolean. So basically, your code is simply echoing a true value, which translates as 1 when converted to a string.

Related

PHP script inside of string?

Is this possible?
What I am trying to accomplish:
Create a html template in the form of a string
Inside the string, add a script, something like include 'php/countries.php';
Echo entire string to html page
Everything but the 2nd step works. I would like to see a php file echo the question being asked, onto the html page, including an echo from another php file.
EXAMPLE
echo "<div id=\"first\"><?php include \'countries.php\'; ?></div>";
I have tried the above, as well as the below:
EXAMPLE
echo "<div id=\"first\">".include 'countries.php'."</div>";
Would this require eval?
Any and all help is appreciated.
Seems a bit silly, but you could do the following:
echo "<div id=\"first\">" . file_get_contents('countries.php') . "</div>";
Or...
echo "<div id=\"first\">";
include "countries.php";
echo "</div>";
Or...
$externalfile = compileexternal('countries.php');
function compileexternal($file) {
ob_start();
require $file;
return ob_get_clean();
}
echo "<div id=\"first\">" . $externalfile . "</div>";
If none of these are what you need, please update the question. There are a dozen ways.
You can use
eval()
But it is not a good practice.
You can use a regular expression.
For example, your string could be;
<div id="first">{{countries.php}}</div>
You'd then do;
$string = "<div id='first'>{{test2.php}}</div>";
echo preg_replace_callback("/(\{\{.+\}\})/", function($matches) {
include_once( str_replace(array("{", "}"), "", $matches[0]));
}, $string);
Check the file exists if( file_exists() )
Check the file can be included (we don't want to include ../../../../../etc/passwd

Best way to combine PHP with HTML in CodeIgniter?

I've took over a PHP app which code is quite a mess so before making any major changes I've decided to rewrite it to MVC (CodeIgniter). As for pure html sections I use $this->load->view(file); technique, but I'm not sure how to cope with something like this:
echo "<tr>";
echo "<td class=\"border szczegolyTd\">";
echo "Kamp.: ".$kampania[$kamp]['idProject'];
echo "<br />";
echo "<b>".$kampania[$kamp]['name']."</b><br />";
echo "<div class='szczegolyDiv'><a class=\"pokaz szczegoly\" href=\"?pokaz=".$kampania[$kamp]['idProject']."\">";
echo "SZCZEGÓŁY";
echo "</a></div>";
if (isset($kampania[$kamp]['timestamp'][$iloLeftCustomers-1])) echo "<br />Dane od: <br /><b>".$kampania[$kamp]['timestamp'][$iloLeftCustomers-1]."</b>";
echo "<br />do: <br /><b>".$kampania[$kamp]['timestamp'][0]."</b>";
//echo "<br />".$ilOstatnichRozmow;
polacz();
$querySpr = mysql_fetch_assoc(mysql_query("SELECT COUNT(*) AS ile FROM lista WHERE user=".$_SESSION['loginid']." AND kampania=".$kampania[$kamp]['idProject'].""));
rozlacz();
if ($querySpr['ile']==0) {
echo "<div id=\"".$kampania[$kamp]['idProject']."\" class=\"tabDodaj\">DODAJ DO OBSERWOWANYCH</div>";
}else{echo "<div class='komunikatMasz'>Masz tę kampanię na liście.</div>";}
echo "</td>";
I'm a beginner in CodeIgniter (and MVC in general), so I don't know all its features and which to choose. Perhaps it's not possible to seperate these 2 technologies completely - so it's more elegant to mainly use html and escape php scripts with <? ?> or to use php and echo html parts?
You can always write html in the template file and insert php in it to loop or echo.
echo "<tr>";
echo "<td class=\"border szczegolyTd\">";
echo "Kamp.: ".$kampania[$kamp]['idProject'];
echo "<br />";
Could be:
<tr>
<td class="border szczegolyTd">
Kamp.: <?php echo $kampania[$kamp]['idProject']; ?>
<br />
Putting code in those PHP tags wil actually fire the call in place. Mind you, to keep the html clean of bussines code make sure you only use echo, foreach, for or if in it.
In CodeIgniter you could render a view file and insert into a "partial" view and just echo it in the main template using TRUE for the 3rd parameter. This only buffers the output instead if immediatly outputting it.
$data['content'] = $this->load->view('ding/templatefile',$vars,TRUE);
if you are really new, please follow this tutorial its nice && informative.
yes it is possible, the best use is short tag + equal sign <strong><?=$variable?></strong> and it echoes whatever is in $variable, whenever you use foreach() use either
foreach($elements as $element) {
$string = "";
$string .= "new line" . $element->id . "<br>";
$string .= "line 2" . $element->name;
echo $string;
}
or just echo lines as you wish
foreach($elements as $element) {
echo "new line" . $element->id . "<br>";
echo "line 2" . $element->name;
}
but remember, before going in to foreach loop, please check if you have valid $variable to go thru. (empty(), isset(), $variable != FALSE...)
note:
if you need condition while echoing basic text use
<strong><?=(condition) ? 'TRUE' : 'FALSE' ?></strong>
example
<strong><?=(isset($variable)) ? $variable : '' ?></strong>
I would advise you go read up on the flow of how a MVC works, but this should point you in the right direction.
In the controller you instantiate the model of the data like:
$this->load->model("lista");
Then,
$data = $this->lista->getCountList($_SESSION['loginid'], $kampania[$kamp]['idProject']);
where in the lista model you have the function:
getCountLista($loginId, $projectId)
which does this part:
return mysql_fetch_assoc(mysql_query("SELECT COUNT(*) AS ile FROM lista WHERE user=".$loginId." AND kampania=".$projectId.""));
Then you pass the returned data to the view
$this->load->view(file, array("listData" => $data));
and in the view:
$listaData[$kamp]['idProject']
It creates an variable in the view foreach item in the array passed in the view.
I commend you to read documentation about MVC.

PHP echo adding functions

What I am trying to do is get an echo of the following php call and subtract 14.1% from the displayed number.
The code:
<?php echo $program->current_amount(); ?>
Can I add arithmetic functions to this in order to display the 14.1% deduction?
I think you're looking for a basic math operation in your output that has no effect on a database or anything else, correct?
If so, do something like the following:
<?php
// Set values
$current_amount = 100;
$pcnt_off = 14.1;
// Do the math
$out = $current_amount - ($pcnt_off/100) * $current_amount;
// Output
echo $out . " is " . $pcnt_off . "% off of " . $current_amount;
?>
http://codepad.org/RqF8cuvN
More specifically to your case:
<?php echo $program->current_amount() - 0.141 * $program->current_amount(); ?>
You can perform expressions inside an echo statement, yes; just wrap it in a (), so:
<?php echo ($program->current_amount() - .141); ?>
It may not even be necessary to use (). Incidentally, if your environment supports short tags, you can simply do:
<?= $program->current_amount() - .141 ?>
Keep in mind, though, that that code won't actually remove 14.1% from your number--you would want to multiply by .859.

printing process output in realtime

I am using PHP 5.3.4 with Apache 2.2.17 on a Windows 7 x64 system. I would like to have my PHP page output the result of a system call in real-time to the user's browser. To that end, I have configured output_buffering=Off in php.ini and created this code:
<?php
ob_implicit_flush(true);
ob_end_flush();
system('ping -n 10 www.google.com');
?>
The result of the ping is printed in real-time, but I also get a PHP diagnostic error and callstack at the top of my page that says:
Notice: ob_end_flush() [ref.outcontrol]: failed to delete and flush buffer. No buffer to delete or flush in index.php on line 3
What do I need to do to either correct or suppress this error?
Update
If I change ob_end_flush() to $a = 1/0; I get a similar error and the output is realtime in all browsers. Is it something about the way the exception is printed that causes this to work?
some web browsers buffer the first x bytes before they start to render a page, under certain conditions.
try just outputting lots of whitespace first
I have a solution that works, but it is non-performant and icky. I throw an exception, but hide the exception dialog.
<?php
ob_implicit_flush(true);
// Something about the way exceptions are thrown causes Firefox and Chrome
// to be able to display the results of the system call in real-time rather
// than having to wait for the call to complete. So, I just hide the
// exception message. IE9 works with or without this.
echo "<div style=\"display:none\">";
$a = 1/0;
echo "</div>";
echo "<pre>";
system('ping -n 5 www.google.com');
echo "</pre>";
?>
To auto-scroll to the bottom of the page, I add some javascript:
<html><head>
<script language="javascript">
var int = self.setInterval("window.scrollBy(0,1000);", 200);
</script>
</head>
<body>
<?php
// insert above php code here
// stop scrolling when the execution finishes
echo '<script language="javascript">int = window.clearInterval(int);</script>';
?>
</body>
</html>
EDIT
#Chris's answer shows a much better solution.
echo '<div style="display:none">';
for ($a = 0; $a < 768; $a++)
echo ' ';
echo '</div>';
Just add this to flush the buffer:
if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) {
echo "<div style=\"display:none\">";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo "</div>";
}
It has to be inside the loop. or between two output you need to show in real-time.
AND here's the shorthand trick:
add this:
if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) {
echo "<div style=\"display:none\"></div>";
}
ob_end_flush() flushes the php output buffer, and requires an active output buffer created with ob_start().
I think you just want to call flush() to send the data to the client.
<?php
ob_implicit_flush(true);
flush();
system('ping -n 10 www.google.com');
?>
In your code, the error is pretty easy to interpret.
You call ob_end_flush() on line 3, but (like the error says), there is no output to flush. In essence, line 3 is useless because no output has been sent, so deleting the line will fix the error. If this is incorporated into a larger file, you might need to keep ob_end_flush() because some output may already have been captured.
EDIT: Since you need to flush it, either:
a: add ob_start(); to the top of the file.
b: replace ob_end_flush(); with flush();
EDIT2: Since the first didn't seem to work, this is the best I can offer: How to echo output in real time, (before script finishes)?

How do I remove text from the console in PHP?

My goal is to print an updating progress percentage to the console (in both Linux and Windows). Currently I just print out the percentage each 10%, but I would prefer that it updated itself every 1% without filling the screen with percentages.
Is it possible to remove text you have written to the console in PHP?
echo chr(8);
will print a backspace character.
very simple
Note the example below
$removeLine = function (int $count = 1) {
foreach (range(1,$count) as $value){
echo "\r\x1b[K"; // remove this line
echo "\033[1A\033[K"; // cursor back
}
};
echo "-----------------------------\n";
echo "--------- Start -----------\n";
echo "-----------------------------\n";
sleep(2);
$removeLine(3);
echo 'hi';
sleep(2);
$removeLine();
echo 'how are you ?';
die();
See Zend_ProgressBar
PEAR's Console_ProgressBar is useful for this sort of use case.
To clear the console entirely, you can use:
if($_SERVER['SHELL']) {
print chr(27) . "[H" . chr(27) . "[2J";
}
which is quite a bit easier than keeping track of how many characters to backspace.

Categories