0

I need to display most of a page's content before outputting the content from a function. The function takes a while to execute, and returns some content for the page. I need the rest of the page to display first, then run the function, and then 'insert' the function output.

It would seem that I'd need to use ob_start at the beginning of the function, then store that data in a variable with ob_get_content(). But I'd also need to run the function after the rest of the page displays.

Here's some code I have tried without success (this is the content area inside the body tag):

<div id='part1'>
   <p>here is part 1 of the content</p>
</div>
<div id='part2'> // this is where the function output will be inserted after processing it
   <p>part 2</p>
<?php echo long_function();?>
</div>
<div id='part3'>
   <p>this is part 3 of the content
</div>

<?php
function long_function() {
   // some process that takes a long time to get data
   // and stores it in the $part2_content
   return $part2_content;
}

The result should be that the part1 and part3 div content should be displayed. And then, when the long_function() finishes with gathering up it's data, that data should be output in the 'part2' section.

I've tried to put an ob_start() at the beginning of long_function(), then $part2_content = ob_get_contents() to store that output data (without an ob_flush).

I think that I may need to add some sort of DOM 'write' to the 'part2' ID, but not sure of the right combination to accomplish.

Rick Hellewell
  • 1,032
  • 11
  • 34

3 Answers3

1

Based on this answer which is completely acceptable: https://stackoverflow.com/a/46871956/17292588

PHP is a server-side programming language. It gets executed when you request a page. So you cannot execute it after the page has been loaded. If you need to check if something has loaded on the client side, you'll have to use a client-side programming language like JavaScript.

I suggest you to putting this long_function in a another route and request it with Ajax during (or after) loading page.

Maria Raynor
  • 342
  • 1
  • 9
1

I believe you can't do the server side rendering. php is back-end language, that run the hole script file, then last thin print the output

for example: in a function: you cant return then call code after

function sayHi(){
    $word = 'hi';
    return "bye";
    echo $word; // this code will never work :) 
}

sloution ?

so you need to use Clint side rendering

for example use ajax

AJAX stands for Asynchronous JavaScript and XML. AJAX is a new technique for creating better, faster, and more interactive web applications with the help of XML, HTML, CSS, and Java Script.

A. El-zahaby
  • 1,130
  • 11
  • 32
1

Based on the answers provided and links (as well as remembering the PHP is server-side so can't change things after the page is rendered), I came up with this code which worked for my purposes. Change the <some-page-on-your-site> to the page you want to get as needed.

I included a CSS-only spinner so you can watch something while the Ajax request is working.

<!DOCTYPE html>
<html>
    <head>
<style>
/* for the loading spinner  */
#spinner {
    display:none;
    position: fixed;
    margin: auto;
    width: 30%;
    background-color: white;
    top:40%;
    left:30%;
    border:thin solid darkblue;
}
.spinner {
 border: 8px solid gray;
    border-radius: 50%;
    border-top: 8px solid green;
    border-right: 8px solid lightgreen;
    border-bottom: 8px solid green;
    border-left: 8px solid lightgreen;
    width: 30px;
    height: 30px;
    -webkit-animation: spin 2s linear infinite;
    animation: spin 2s linear infinite;
}
.spinner_book {
    transform: rotate(360deg);
    -webkit-transform: rotate(360deg);
    overflow: hidden;
    transition-duration: 0.8s;
    transition-property: transform;
}

@-webkit-keyframes spin {
    0% { -webkit-transform: rotate(0deg); }
    100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}
</style>

    </head>
<body onload='loadDoc()'>
    <div>
        <div id='ajax_results'>
            <div align='center'>
                <p align='center' class='spinner'></p>
                <p align='center'>Please wait we get the data ...</p>
            </div>
        </div>
    </div>
<script>
function loadDoc() {
    const xhttp = new XMLHttpRequest();
    xhttp.onload = function() {
        document.getElementById("ajax_results").innerHTML = this.responseText;
        }
    xhttp.open("GET", "<some-page-on-your-site>");
    xhttp.send();
}
</script>

</body>
</html>

You can add query parameters to the <some-page-on-your-site> .

Note that the initial text in the 'ajax_results' div (the spinner and message) will be replaced by the contents of the request. So nothing needed to remove the spinner after the request is completed.

Thanks for the answers which helped me get to my solution. I hope this helps others who wander here.

Rick Hellewell
  • 1,032
  • 11
  • 34