flush functions are deleting my html temporarily - php

Notice: Yes I did ask this question once before but it got immediatly marked as a duplicate although the linked duplicate had almost nothing to do with my question.
I wrote a php script that is executing my application to download images from the web. And in order to show some kind of progress being made on my website I used flush to echo out some information for the User. Here is my code:
echo '<li class="list-group-item list-group-item-info">Starting to gather data!</li>';
ob_flush();
flush();
$url = $unsplash;
$cmd = $unsplash . ' - ' . $amount;
exec($cmd);
echo '<li class="list-group-item list-group-item-success">Gathering Data Completed</li>';
ob_end_flush();
The code I am using does work without any problem (besides this one) so there is no error there!
Unfortunately every kind of HTML content I write under my php script is being deleted for the duration of the script executing (which sometimes can take up to 5 minutes). But immediately after the script finished the Content beneath reappears. Another thing worth mentioning is, that when I open DevTools in Chrome (F12) during the scipt is being executed is shows nothing!
Am I doing something wrong ? I cant seem to figure it out...
Thank You

I'm not sure, exactly what you mean by "being deleted", but what you need to take into consideration is that output buffering can happen at multiple levels (PHP, Web Server, Client UA, etc..).
If the output from your script does not appear right away, it's likely that you have output_buffering enabled at a higher level (i.e. in your php.ini or other loaded configuration). Because output buffers cascade, they flush at each level. Check your phpinfo() and if you see a value other than 0 for output_buffering, then you need to edit the php.ini file showing in phpinfo() under Loaded Configuration (near the top) and change that value to 0 then restart your parent PHP process.
Another thing to consider is that some browsers won't render some HTML block-level elements like <div>, <ul>, etc... until they are closed. The content may have arrived at the client, but some browsers don't process the rendering of the content until the block level element is complete. So a better way to test that the output is being received on the client end without these variable nuances might be to send a text/plain Content-type header from your PHP to get the HTML rendering stuff out of the way. header('Content-type: text/plain'), if turning off the output_buffering in PHP still doesn't give you the desired result.

Related

white page when content-length > 8000

On a private project I stumbled over a weird problem: On page load when the header-information Content-Length reaches 8000 and I add a single character (or more) to the output(e.g. <a>12</a> instead of <a>1</a>), the page will be white and the body (!) of the HTTP-Packet will be empty (also: Content-Length: 0). Debug information (e.g. with PhpConsole for Chrome) is transported correctly, though and when I parse my code via command php index.php no error is thrown and the content of the page is returned correctly.
Since this problem happens at exactly 8000 I guess it is related to a setting made by a human and not some buffer overflow or something similar. Does anyone know that problem and know how to fix it?
Update:
My problem seems to be related to this, which according to the comment is not a bug but a feature called "chunked encoding".
I could quickfix my problem by adding header('Content-Length: '. ob_get_length() ); to the end of my script, but I'd like to understand the problem. So if anyone could explain to me where this problem comes from and how I could fix it permanently and in an appropriate way, that would be great. :)

PHP Not Echoing in the right place

I'm running some PHP code on my WordPress site and when the PHP runs to echo out some information it doesn't echo it in the right place. An abbreviated version of the code is:
<div class="description cms">
<div id="home_left_middle">
<h2>Search By Category</h2>
[xyz-ips snippet="Category-List"]
</div>
</div>
The shortcode is for the plugin XYZ PHP Code which is basically just a way to use 'includes' in WordPress posts. I've set up some customization in the WP database but it's just basic database calls. All the information is returned successfully from the database so there's no issue there. The PHP code I'm using there is:
$sql = "SELECT * FROM wp_categories_table";
$result = $wpdb->get_results($sql);
echo "<ul class='category_list'>";
foreach( $result as $results ) {
$category = $results->category;
$number = $results->number_of;
$category_html = htmlentities($category);
echo "<li><a href='?search-class=DB_CustomSearch_Widget-db_customsearch_widget&widget_number=preset-default&cs-all-0=&cs-post_cat-1=".$category_html."&search=Search'>".$category." (".$number.")</a></li>";
}
echo "</ul>";
What happens is that when the PHP code runs, it echoes it right after the div.description (and before the div#home_left_middle) and just the H2 remains in the home_left_middle div. That's not where the code is being run.
The curious thing about this is that I was using the exact same code on another site (I duplicated this site because we were just changing servers, exact same content though) and it works fine on the other server. This is a VPS so I'm wondering if there is some sort of PHP extension that I haven't installed on the server correctly that may be causing this? I know that's a bit of a reach but I'm confused as to why the exact same code, in the same version of WordPress and using the same theme and CSS files would cause different results on two different sites. The only difference I see is possibly the server unless I'm overlooking some small error?
EDIT
For those asking about an output buffering issue, I've recently copied the php.ini file over from the last server and the output buffering code looks like this:
; output_buffering
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
So it appears to be commented out.
Like maioran84 suggested in the comments, this is probably some issue with the output buffers. I would suggest you copy over the php.ini file from the working site to the non-working site server.
Looking inside the PHP configuration file, there are a few settings that may be causing the output to be displayed before wordpress is ready for it.
; Implicit flush tells PHP to tell the output layer to flush itself
; automatically after every output block. This is equivalent to calling the
; PHP function flush() after each and every call to print() or echo() and each
; and every HTML block. Turning this option on has serious performance
; implications and is generally recommended for debugging purposes only.
; http://php.net/implicit-flush
; Note: This directive is hardcoded to On for the CLI SAPI
implicit_flush = Off
output_buffering = 4096
Looking at the WordPress documentation for add_shortcode(), the following block of text really stood out. You can easily change all of your echo statements to append the value to a string and then return the string as a whole.
Note that the function called by the shortcode should never produce output of any kind. Shortcode functions should return the text that is to be used to replace the shortcode. Producing the output directly will lead to unexpected results. This is similar to the way filter functions should behave, in that they should not produce expected side effects from the call, since you cannot control when and where they are called from.
https://codex.wordpress.org/Function_Reference/add_shortcode
Hopefully this will help you with this issue, but I have never heard of any error like this happening before.
I know this question is old and has been resolved, but I had the same issue and managed to resolve it differently, so I thought I'd share :)
I was using the same wordpress plugin you were, XYZ php code, and it was outputting above the div it was being called in. I switched to a different plugin called 'PHP Code for posts', which works exactly the same was as XYZ, expect with a slightly nicer code editor and it outputted exactly as expected.
It's odd because I normally use XYZ in my WP builds and its always worked fine, so all I can guess is there's a bad plugin interaction. Obviously there's a difference in the way the plugins work, but I'm not feeling intrepid enough today to figure out what ;).

I need to add content at the end of each page

I have a client, whose website has 108 different php static pages, and we need to add some content at the end of each page. I want to avoid doing this manually. Is there any way I can add a link at the end of each page programmatically by using .htaccess or php?
Its a limited hosting account, no ssl
You can use auto_append_file
webbiedave's answer looks simple - but what happens when you append the content to...
<html>
...
</html>
Whether the text is rendered, and how it is rendered will depend very much on the browser. Also, as per the link provided "If the script is terminated with exit(), auto-append will not occur" - while PHP does a good job of cleaning up the resources at exit, it is still good practice to explicitly call exit when the code should terminate.
Although it's still not a generic solution, I'd go with auto prepend script containing something like:
<?php
register_shutdown_function('add_footer');
function add_footer()
{
// try loading a javascript to render the required text
print '<script type="text/javascript" src="/somepath/addfooter.js"></script>' . "\n";
// and for browsers with js disabled but which will render the text include it inline
print '<noscript>' . $include_as_static_text_here . '</noscript>';
}
(IME a script tag appended after the closing html tag is generally acceptable to most browsers even though the resulting html is not well formed - and in the few cases where it is not, the worst that happens is that the script is ignored).
Then in addfooter.js, add the content to the end of the body of the document.
Obviously this will result in the content being sent twice in some cases - solutions to this should be obvious - but I've omitted them for reasons of time and clarity.

server side code crashing only IE?

Strange issue: PHP runs a nested foreach that generates a string (basically a calendar that shows people's holidays).
This string goes in $data['grid'] and sent to the view. var_dump shows: string(188263)
The string is printed out fine in the webpage when viewed with FF and Chrome but for some reason when viewing with IE6, 8 and 9 (not tested in 7) it crashes the browser every single time; it hangs and nothing ever appears on screen.
IE can show the string when it's printed out in the controller, so before it's passed to the view.
This works fine in IE:
print $str; die;
$data['grid'] = $str;
$this->load->view('conge', $data);
This crashes IE:
//print $str; die;
$data['grid'] = $str;
$this->load->view('conge', $data);
The total "weight" of the page is 192KB and there is no JS running. It feels like a PHP / memory problem but the fact that the "bug" only exist in IE makes little sense.
Any ideas how this can be debugged?
EDIT: When I saved the rendered output from FF in to a static HTML file and load that in IE it sill crashes. The string was printed out without line breaks (loooong) but when I add \n the problem persists. Anyway, one step closer.
EDIT2: It seems to be due to errors in the HTML markup that cause IE to crash (?!). Case closed!
The serverside code cannot crash the browser.
The HTML file generated can crash the browser so you need to examine the outputted HTML carefully.
Point the w3c validation service at the URL and see what it comes back with.
If that yields no results start commenting out large section of the header, then the body etc until you get a successful render then you can investigate a small section of code instead.
Btw I'm assuming 192k includes images, CSS etc else that's a monster HTML file!

Why is my 301 Redirect taking so long?

In a long tiredsome quest to speed up my site, I have figured out something is wrong with the redirection: currently my index.php handles all the homepage redirections via PHP header location 301 Redirect Permanently: website.com >> website.com/en/home and website.de >> website.de/de/home etcettera etcettera (around 20 for this multilingual website) it takes anywhere from 200ms to 6000ms to do the redirecting. Check out the waterfall!
After that, the page loads in a thunderbolt's blink of an eye!
What a waste of time wouldn't you say? What is the server doing all this time?
After careful examination, my best guesse is: ITS DOING LAUNDRY!
I am almost giving up on PHP for this!
Any and all clues to my puzzling prob are very welcomed +1
A. Given facts: Apache/2.0.54 Fedora, PHP 5.2.9. there is no database: just flat php files with around 15 php includes that completes my page with headers and footers). YSlow Grade: 92/100! Good page Speed: 93/100! javascript and css are as much as possible combined. Cache controlls seem well set too (as proven by the grades). Whats missing in those 7 points out of 100: not using Keep-Alive (beyong my controll in shared hosting and not using Content Delivery Network. I can live with those missing 7 points, but this is major hit on speed!
B. Furthermore: i recently was given great insights over here that i should use url rewriting via htacces. Point taken, BUT, perhaps there is sometin else wrong here that i should correct before moving on to the for me more difficult apache regex syntaxes.
C. Faster way: When I php include the intended homepage, instead of redirect, then all loads fast, but the url is not rewritten: it sits at website.com on the browser bar, whereas i wish after including it to become website.com/en/home. Is this possible with PHP? To include+change the current address of the url, too?
Conclusions: you can redirect using index.php, or using .htaccess. Sofar from my tests (coming from the genius answers below!THANKS EVERYONE!) the latter seems unmatched in speed: much faster redirecting than a php redirect! reducing the redirect to shorter than the first dns lookup.
see here how to do this correclty for multilingual site
Damn, I hate getting stuck with this kind of problem. You need to eliminate some variables.
First I should point out that PHP will not flush all of its own headers until you start outputting things (or, if the output_buffering(?) ini directive is set to x bytes, until you have output x bytes). So the following script will not finish "sending headers" until the very end:
<?php
header('Content-Type: text/pants');
sleep(6);
header('Ding-Ding: time to put the socks in the dryer');
echo "z"; // headers are sent here
What happens to the call to en/home if you put exit; or echo "wheeeee"; exit; at the very top of that PHP script? Then what happens when you substitute it with a plain, empty file? If the php script with exit is slow but the plain text file is fast, the PHP interpreter is probably playing funny buggers. If you still get the delay for both, you've eliminated the actual response generation as the cause (but I'm still trying to come up with some ideas if this is the case).
Also, can you ssh to the server? If so, can you try wgetting the same page from inside the server? If you can without the speed problem, I would be looking at the client side. If you can't SSH, you could try doing a request from PHP, though I'm really not sure if this will work:
<?php
$context = stream_context_create(array(
'http'=>array(
// send request headers if you need to
'header'=>array(
'Foo: Bar',
'Bar: Baz',
),
),
));
$start = microtime(true);
$response = file_get_contents('http://yourserver.com/', null, context);
$end = microtime(true) - $start;
var_dump($end);
// for some bizarre reason, PHP emits this variable into the local scope.
var_dump($http_response_header);
Have you tried doing the same request from other machines, or other places in the world? This can confirm or deny if it's just your machine.
Another thing you can try if it is the response generation is to do a little bit of hack-profiling on the production server. I hate having to do this stuff, but sometimes your code just refuses to behave on the production server like it behaves in your development environment or on staging. Do this to the script that generates /en/home:
<?php
// put this at the very top
$rqid = uniqid('', true);
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [START] '.microtime(true).PHP_EOL);
fclose($h);
// do all that other wonderful stuff, like laundry or making a cup of tea
// put this at the very end
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [END] '.microtime(true).PHP_EOL.PHP_EOL);
fclose($h);
Run a few requests against it, check to make sure 'crap.log' is getting stuff written to it (check permissions!!), and then you'll have some data that will show whether there is something in your script that needs to be investigated further as the cause of the slowness.
Oh, did I mention MySQL indexes? Are you doing any queries during the request? Have you added all of the proper indexes to the tables?
Steven Xu raises a good point in the comments for your question - are you sure the program you're using to generate the waterfall is giving you good info? Try installing Firebug if you haven't already, click the little firebug icon in the bottom right of firefox and make sure the "Net" panel is open, then re-run your request and see if the waterfall is consistent with the results you're seeing in the program you used.
Also, I know this is kind of a boneheaded suggestion and I apologise, but I think it needs to be said: your host doesn't allow ssh and only uses PHP 4? I would seriously consider another host. It may even solve this specific problem.
I will add more stuff as I think of it.
If it is indeed the headers taking ages, then your JS/CSS/HTML is irrelevant.
You can do the forwarding in .htaccess.
RewriteEngine On
RewriteRule ^$ en/home [R=301]
This will essentially send the same header, but it won't invoke the PHP engine first to do it :)
Update
On closer inspection, it would seem to me that your en/home page is taking the longer time to download.
I think Ignacio Vazquez-Abrams may have the answer: after you call header() to do the redirection you need to call exit() to cause the PHP script execution to stop. Without that the script will keep executing, sending output to the browser, until the end. Since the browser has to wait for the server side script to end before performing the redirection that could cause the problem.
Update
Just read Alex's update and he seems to be correct. The /en/home page is where the time is.

Categories