I am not well versed in php. I tried different answer from stackoverflow but was not successful in solving the problem.
I got a HTML form with a submit button. After submitting I call a php script and which in turn calls an executable file which runs some algorithms on the submitted data from the html. At the end I echo the result of the analysis through the php.
<?php
$ex=shell_exec("...");
if($ex == "Run Successfully\n"){
echo"<html>
<meta http-equiv= refresh content='0.1;URL=--.txt'>
</html>";
}
?>
Till this works fine but my algorithm takes 30-40 sec to run and all that time my original html page remains in screen which looks like nothing is happening there. So I created a new html page with a progress bar animation. Now I want to show the progress bar while the executable is running and when the result is available I want to replace the progress bar page with the result page as before.
I tried echo file_get_contents("waiting.html");
header ("location: waiting.html");
But none of them works as I planned. All the time they are coming up only after the executable finish working and not before that.
If someone can help me with some suggestion I shall be grateful.
Thanks in advance.
This is where jQuery and AJAX would work very nicely. What you could do is start with the loading animation, and use jQuery to call the php file with the shell_exec with ajax. Once the ajax is .done(), then you can replace the text with the results. If you need me to clarify, just let me know.
However, if you don't want to use AJAX, PHP is run line by line. Therefore, you would want to put your progress bar before the shell_exec. This would mean that you would not be able to use header location since headers have already been sent.
Edit (AJAX Example):
This would be a quick example of how to make this happen.
Create two php files:
progress.php
Load jQuery
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
url:'algorithm.php',
type: 'post',
cache: false,
success: function(data) {
//Replace with how you want to format the page
}
});
});
</script>
Loading Bar
algorithm.php
<?php
$ex=shell_exec("...");
if($ex == "Run Successfully\n"){
die('{"status":"success"}');
}
?>
Now you don't have to use json as an output. You can also have html output. Let me know if I should clarify anything.
Related
I was messing around with php to better understand it's execution. I found that when this same code is run with the php block placed at the end of the page, it produces a different output. Can somebody explain it to me. This difference made me go crazy for days when I was working on my mini project.
<?php
if(isset($_POST["btn1"])){
echo "btn1";
die();
}
?>
<html>
<body>
<button id="btn1" name="btn1">btn1</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$.ajax({
type:'post',
url:'',
data:{'btn1':true},
datatype:'text',
success:function(val){
alert(val);
}
});
});
});
</script>
</body>
</html>
PS. This code when run as is, produces the proper output i.e. it alerts "Hello". But when the php code is written at the end, it alerts the html code of the whole page...
PHP is processed inline unless it is wrapped in a function call, a class declaration, or a control statement since it is intended to be included within html. PHP = PHP Hypertext Preprocessor. http://php.net/manual/en/intro-whatis.php I repeat, PHP is processed inline. The server does not load a file and run only the PHP or the HTML, it starts at the beginning of the file and processes the entire file unless there is a function call, class declaration, or some other control statement.
When your initial page loads as written, the 'btn1' parameter hasn't been posted so the if statement is skipped and the server continues executing the page to return the html in the rest of the doc.
When your ajax call reaches the page, it starts at the top and this time the if statement is true because btn1 is set. The die() call tells the server to just quit going through the rest of the page so you get "btn1" from the echo statement.
If you remove the die statement, you'll get the "btn1" text and then the rest of the page from the ajax call. If you put the php block at the end of the page, you'll get the whole page and then the "btn1" text. If you shove that php clock into the middle of the html, the ajax call will return the page with "btn1" in the middle where the code is.
The situation:
User visit some fast loading page, that makes an AJAX async request to some slow PHP script, that loads, for example, for 30 seconds
After 3 seconds user clicks some link to go to another fast loading page, but browser waits 27 seconds to finish AJAX request to slow script, and only after that starts to load next page
How can you solve this problem? How to tell web server to interrupt processing the request, started with defined AJAX call?
PS. abort() is not the solution
PPS. The code example: my page includes filter of shop products, that loads longer that other page components. After first load filter is cached - next times it loads fast. So when page loads, I don't show filter, but add a JS, that calls current page again using AJAX, adding some parameter (SHOW_FILTER). If page receive this parameter - it shows filter...
<div id="catalog_filter_container">
<?if($_REQUEST['SHOW_FILTER'] == "Y"):?>
... filter code here ...
<?endif;?>
</div>
<?if($_REQUEST['SHOW_FILTER'] != "Y"):?>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
url: "<?=$APPLICATION->GetCurPageParam("SHOW_FILTER=Y", array("SHOW_FILTER")); // get cur URL with adding param SHOW_FILTER=Y ?>"
})
.done(function(html) {
$("#catalog_filter_container").append($(html).find('#catalog_filter_container'));
});
});
</script>
<?endif;?>
If I understand you correctly it is not neccessary to have an ajax-call because the page is reloaded anyway. This seems like something you can do server-side only (with sessions).
Something like this: (If the thing you want to achieve is store a value to filter when filter not set and display the value from filter when it is set)
<?php
session_start();
?>
<div id="catalog_filter_container">
<?if($_REQUEST['SHOW_FILTER'] == "Y") {
$_SESSION['filter_content'] = 'bla bla bla';
}
else {
echo $_SESSION['filter_content'];
}
?>
</div>
Try using a cron job to run the queries separate from page loads and cache the results on the server. Then have your AJAX request return the cached content.
I am using pdfcrowd API for generating PDF from my dynamic PHP webpage, in which I am getting some data from DB and also running some jQuery functions with setTimeout function having 2 to 3 seconds delay at the bottom of page inside document ready function of jQuery.
This jQuery functions I am using to set page layout height dynamically based on content using Lightweight Responsive jQuery - Waterfall plugin, which takes some time to do that.
So, when I try to download PDF, it downloads page without running my JavaScript/jQuery function, which delay approx 2 to 3 second in it.
Code detail that I am using:
MyWebPage Code looks something like this:
//HTML + PHP code here at top of page
//jQuery code to set page height dynamically
function setContainerHeight(containerDiv) {
//function code here..
}
$(document).ready(function() {
setTimeout(
function() {
$(containerDiv).waterfall({gridWidth:[0,500,1000,1500,2000],gap:10});
setTimeout(function() {setContainerHeight(containerDiv);},2000);
},1000
);
});
Download Page
$client->setPageLayout(Pdfcrowd::CONTINUOUS);
$pdf = $client->convertURI($myWebPageUrl);
// Set HTTP response headers
header("Content-Type: application/pdf");
header("Cache-Control: no-cache");
header("Accept-Ranges: none");
header("Content-Disposition: attachment; filename=\"Resume.pdf\"");
// send the generated PDF
echo $pdf;
Please help me in this, how I can delay the PDF scan until my page loads completely.
Thanks in advance.
Since you can't hold webpage to render, as your JavaScript function is running after page load as usingsetTimeout, you should do whatever is required with page load only.
So, You should try calling your function setContainerHeight() after plugin work completion, means you should try call back function of plugin.
And remember to remove setTimeout as they will not be required, after using callback function. Moreover, if your plugin doesn't have callback, so you should mind calling your function from plugin file, though this is not correct way, but it should do the trick.
In your case, you should search for function named sorting in your waterfall API and add your function call in last of it.
Hopefully, this helps you..!!!
Your question does not clarify what the problem really is, may be a problem of the javascript not knowing when the PDF file has loaded fully, can you call it by an ajax call?
If you are loading the PDF to an IFrame you could try this:
$("#iFrameId").on("load", function () {
$(containerDiv).waterfall({gridWidth:[0,500,1000,1500,2000],gap:10});
});
If the problem is in php, may be the output of the PDF beeing slowed by the api you could stop the output buffer until the process is done by:
ob_start(); //at the begining
//Your code until echo
ob_end_flush(); //at the end
I've been googling the whole day for this... I'm still a beginner at html/css/php/javascript, so I probably have some rookie mistakes, but that's why you guys are here to help me!
So, I have a dynamic website with a static template and dynamically loaded content. For example, when I click the "About Us" link, the template remains the same, but the content gets loaded from another .php file and printed out in a iframe in that same index, using the $_GET method. I'm using iframe so I don't affect the template layout. My problem is that my .js file with animations gets executed each time I click any of the navigation links, so it makes my wish to, for example, fade in the whole website once it's loaded impossible. Each time I click a link the entire website would dissapear and fade in again. I don't know did I use Google wrong, but I cannot find the solution to my problem. I only want that script to run once when the page is loaded, not whenever I click a link! Here are some parts of the code:
Part of index.php:
<?php
include('setup/setup.php');
?>
<html>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="javascript.js"></script>
<body>
<div class="wrapOverall">
<div class="header">Logo, language buttons etc.</div>
<div class="wrapMainNav">Main navigation (Home, About us etc.)</div>
<div class="content">
<iframe src=<?php echo "content_$language/$pg.php"; ?> frameborder="0" style="width:951px; height:486px;">aaa</iframe>
</div>
</div>
</body>
</html>
where "content_$language" is the folder from which I get the file, and "$pg.php" is the file itself.
The setup.php file:
<?php
error_reporting(E_ALL ^ E_NOTICE);
if($_GET['page'] == '')
{
$pg = 'naslovna';
}
else
{
$pg = $_GET['page'];
}
if($_GET['lang'] == '')
{
$language = 'cro';
}
else
{
$language = $_GET['lang'];
}
?>
The javascript.js file:
$(document).ready(function() {
$(".wrapOverall").hide(); //Hide the website
$("html").css("visibility", "visible");
var bg = new Image();
bg.src = "images/background.jpg";
bg.onload = function(){ //Load the background image
$("html").css("background-image", "url(images/background.jpg)");
$("html").css("background-repeat","no-repeat");
$("html").css("background-attachment", "fixed");
$("html").css("background-position", "center");
$(".wrapOverall").fadeIn(1000); //Fade in the site
$(".content").animate({height:'468px'},1000); //Animate content loading
}
});
That's about it, if you guys think you need more code I can send it.
Each time you click a link, and the URL changes, the browser makes a GET request to the server for that page. PHP will return the page and the browser will reload it, even if it's 95% the same as the last page you were on. It'll re-render the DOM and hence the $(document).ready event will fire again.
What you're looking to do is to refresh a part of the page without making a GET request to the server for the whole page. To do this you need to use AJAX.
One of the simplest ways to do this is using jQuery's load() method (click for documentation).
Have a look at the documentation and try a simple example, hopefully that will get you started.
NOTE: as has been mentioned already in the comments, there are plenty of frameworks that try to make achieving this functionality easier. Take a look at backbone.js, angularjs and ember.js to name a few. They also add a lot more, so depending on what you're trying to do, might be overkill, but it's worth a look.
Since your javascript is included in every page, it runs each time the page loads, and therefore hides and then shows the whole page. You should exclude it when loading other pages.
Have you tried to call the the iframe content with ajax ? That way the php will be called in the same time than your js functions.
I'm currently in the midst of creating a generator which echoes a random line from a .txt file. All is well and good however I need to have this certain part of the page which echoes the random line refresh when a button is clicked. I've tried multiple methods to no avail and I'm running out of ideas - I'm still quite new to JavaScript/AJAX and have no idea on how to go about it. Any help would be brilliant, thanks!
Use Jquery Ajax to get contents from the file and display the contents into a div
$.ajax({
type: "GET",
url: "yourfilename.txt"
}).done(function( msg ) {
$("#YOURDIVID").html(msg.d);
});
Bind click event of your button
$(function(){
$("#YOURBUTTONID").on("click",function(){
//do your work
});
});
Refreshing logic can be wrapped into a function and called on click of button OR you can use javascript settimeout method.