I´m stuck for 3 days trying to figure it out what is the cause of this problem. Lets go to the details:
A jquery ajax call loads a php file named HELPER, wich when loaded includes another php file called F1 that creates html table trough mysqli queries. Ajax get the response and paste the string in a html DIV. The response is a html table. The web server is apache2.2.
Problem is, the code runs in less than 1 second, but the response takes about 50 seconds. The response is only 20 KB.
Some simple HTML table code.
<?php
if (!$res = $sql->query("A QUERY")) { die('custom error 46'); }
if (!$res->num_rows > 0) { die('custom error 47'); }
$myStr = '';
while ( $row = $res->fetch_object() ) {
if ($row->summary == "1") {
$mysum = " class='qtfck-table-summary'";
$myIsSum = "Sim";
} else {
$mysum = "";
$myIsSum = "";
}
if(intval($row->id_centrodecusto) > 0) {
$mycc = "<input type='checkbox' name='" . $row->id_task . "' value='" . $row->id_centrodecusto . "' CHECKED />";
} else {
$mycc = "<input type='checkbox' name='" . $row->id_task . "' value='' />";
}
$myj = " style='padding-left:" . intval($row->depth) * 10 . "px'";
$myStr = "<tr%s><td>%s</td><td><center>%s</center></td><td><center>%s</center></td><td%s>%s</td><td><center>%s</center></td><td><center>%s</center></td></tr>";
echo sprintf($myStr,$mysum,$row->wbs,$row->depth,$myIsSum,$myj,$row->name,$row->uniqueid,$mycc);
}
?>
Html Table closure
The timmings:
PHP START: 0.92 sec
PHP END: 0.98 sec
JS RECEIVED DATA: 49.50 sec
JS PROCESSED DATA: 49.56 sec
I did some digging and it looks like the apache/httpd process (shell via top command) is going nuts, taking 100% CPU load during the full 50 seconds of wait.
BUT here´s something funny. If I change the string generated by the sprintf function and, let´s say, set some random string, there´s no problem at all.
Some simple HTML table code.
<?php
if (!$res = $sql->query("A QUERY")) { die('custom error 46'); }
if (!$res->num_rows > 0) { die('custom error 47'); }
$myStr = '';
while ( $row = $res->fetch_object() ) {
if ($row->summary == "1") {
$mysum = " class='qtfck-table-summary'";
$myIsSum = "Sim";
} else {
$mysum = "";
$myIsSum = "";
}
if(intval($row->id_centrodecusto) > 0) {
$mycc = "<input type='checkbox' name='" . $row->id_task . "' value='" . $row->id_centrodecusto . "' CHECKED />";
} else {
$mycc = "<input type='checkbox' name='" . $row->id_task . "' value='' />";
}
$myj = " style='padding-left:" . intval($row->depth) * 10 . "px'";
echo "<TR><TD>eZ6OnMCZgygePZeUQHcqbOmHQDxhDF4KzfkgOd198xhPFV2rRezlIqBdJLY2TcNlO0PLUmK6CQI9PQMZgkLrcoeYIYhM0x9xK4yQXIFb5SLdq32</TD><TD>UTuQPG9WCbOswuJMdkkckMoAW49C71IN9qKdk8OAdRRV3ZuCYxM5GEZKrXXrwE7cWHKTcXTiO4KwGjh1ejENvduZvEVkwA3zoHbWkzEjtFa1GMaNzD2rqswEDSoQix2CLziBNiHD8zliSWu5rvU8wd6dodWBvubvog</TD></TR>";
}
?>
Html Table closure
The response to this request is 50 KB in size.
The timmings:
PHP START: 0.78 sec
PHP END: 0.81 sec
JS RECEIVED DATA: 1.13 sec
JS PROCESSED DATA: 1.19 sec
What I have already tried:
Use ob_start() and ob_end_flush().
Set apache mpm prefork SendBufferSize to a higher value, but I believe it was a long shot, as the longer response (50KB) has no problem.
Use echo instead of sprintf.
Anyone has a clue?
Best regards.
I don´t know why but the problem was caused by the "center" html tags. Somehow the presence of the center tags slowdown the response. I just removed them and created appropriate css classes using "text-align: center" and the problem was gone.
I also did try avoiding PHP to echo the HTML. Even then the tags causes problems again.
Here´s the fix. I just don´t have an explanation for it.
Related
I have a form that posts to a script via ajax, the script inserts the form data into a database and using ajax i the refresh the div on the original page which then shows the form as well as a list of records in the database (from the form input)
I hope that makes sense.
My issue is that sometimes, maybe 1 time in 20, the div refreshes too quickly and doesn't pick up on the new data if i refresh the page its there and if i submit a new record both records are then in the list.
I guess i just need to delay the refreshing but i don't know how.
thanks,
php
echo '<div id="cuttingListDiv">';
$sql = "SELECT * FROM `cuttingList` WHERE jobRef = '".$_SESSION["jobRef"]."' ORDER BY pieceMaterialName, pieceThickness ASC";
$results = $dbconn->query($sql);
if ($results->num_rows > 0) {
echo '<h3>Cutting List:</h3>';
echo '<div align="center">';
while($row = $results->fetch_assoc()) {
echo '<br />';
echo '<div class="row">';
echo '<div class="col" align="center">';
echo '<h5>'.$row["pieceMaterialName"] . ' - ' . $row["pieceLength"] . ' x ' . $row["pieceWidth"] . ' x ' . $row["pieceThickness"] . 'mm</h5>';
echo '<br />';
echo '</div>';
echo '</div>';
}
echo '</div>';
}
echo '</div>';
ajax script
session_start();
include '_script_sqlConnection.php';
$pieceLength = strip_tags($_POST['pieceLength']);
$pieceWidth = strip_tags($_POST['pieceWidth']);
$thickness = strip_tags($_POST['thickness']);
$material = strip_tags($_POST['material']);
$materialName = strip_tags($_POST['materialName']);
$sheetID = strip_tags($_POST['sheetID']);
// Swap width & length id width bigger
if ($pieceWidth > $pieceLength) {
$tmpDimm = $pieceLength;
$pieceLength = $pieceWidth;
$pieceWidth = $tmpDimm;
}
$sql = "INSERT INTO `cuttingList`(`orderRef`, `pieceMaterialName`, `pieceThickness`, `pieceLength`, `pieceWidth`, `sheetID`, `pieceWeight`, `qty`) VALUES ('".$_SESSION["quoteRef"]."', '".$materialName."', '".$thickness."', '".$pieceLength."', '".$pieceWidth."', '".$sheetID."', '".$pieceWeight."', '1')";
if ($dbconn->query($sql) === FALSE) {
echo "Error Adding Pieces To Cut List.<br />";
}
javascript
$("#cuttingListForm").submit(function(){
$.ajax({
type: "POST",
url: "_script_ajax_addToCuttingList.php",
data: $('form.cuttingListForm').serialize(),
success: function() {
$("#cuttingListDiv").load(location.href + " #cuttingListDiv");
}
});
});
Use the JS function setTimeout
// example of usage for setTimeout:
setTimeout( function(){
$("#cuttingListDiv").load(location.href + " #cuttingListDiv");
}, 2000 );
In the example you have 2000 milliseconds for 2 second wait before fired the call.
Thanks for you help but i went a different way as i was still having trouble with both of these methods.
At the very top of the div that refreshes I used the php sleep command to wait 1 second, now it works perfectly.
Thanks,
I have a page, index.php, with <select> <options> which act as filters. Through Ajax, information is retrieved from an SQL database and echoed into a <div> on the same page. One of the fields that is echoed contains the URL to another page such as a1701.php. Thus far, everything works perfectly.
However, rather than having the URL displayed, I would like the content of the page e.g. a1701.php to be displayed in the same way it would be if I had used <?php include 'a1701.php' ?>.
I have read a lot of posts on SO but haven't found any describing this situation (maybe I am looking for the wrong thing in which case please advise). Following the advice of other partially-related posts, I have tried several things including:
using absolute rather than relative links with $_SERVER['DOCUMENT_ROOT']
include 'a1701.php'; vs echo "<?php include 'a1701.php'; ?>"
using < instead of < etc.
reloading specific <div>s (I haven't actually tried this because I can't figure out what code I would have to put where to make it work.)
I have tried more than one URL and have checked that each one is correct.
index.php
<script>
function filterQuestions() {
var selectCount = document.getElementsByTagName("select").length;
var str = [];
for (var i = 0; i < selectCount; i++) {
if (document.getElementsByTagName("select")[i].value != "") {
str[i] = document.getElementsByTagName("select")[i].name+"="+document.getElementsByTagName("select")[i].value;
}
}
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("questionList").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","filter.php?"+str.join("&"),true);
xmlhttp.send();
}
</script>
<select name="branch" onchange="filterQuestions()">
<option value="All">All branches</option>
<option value="Number">Number</option>
<option value="Trigonometry">Trigonometry</option>
</select>
<select name="topic" onchange="filterQuestions()">
<option value="All">All topics</option>
<option value="sinrule">Sine Rule</option>
<option value="cosrule">Cosine Rule</option>
</select>
filter.php
<?php
$branch = $_GET["branch"];
$topic = $_GET["topic"];
if($branch != "All") {
$wherefilter[] = "branch = '".$branch."'";
}
if($topic != "All") {
$wherefilter[] = "topic = '".$topic."'";
}
$where = join(" AND ", $wherefilter);
if($where != NULL) {
$where = " WHERE $where";
}
mysqli_select_db($link,"generator");
$sql="SELECT question_name, url FROM questions".$where;
$result = mysqli_query($link,$sql);
echo "<table>";
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['question_name'] . "</td>";
echo "<td>" . $row['url'] . "</td>";
echo "</tr>";
$pagelink = $row['url'] . '.php'; /* URL is correct */
echo"<br>";
echo $pagelink;
echo"<br>";
echo "<?php include '" . $pagelink . "'; ?>";
echo "<br>";
echo "<?php include '" . $pagelink . "'.php; ?>"; /* doesn't work */
include $pagelink; /* doesn't work */
}
echo "</table>";
mysqli_close($link);
?>
a1701.php
contains the content I want included. I have tried including other content too.
Is there a way to achieve what I am after? Am I heading in the right direction?
I can think of 2 ways to accomplish this.
If the PHP file is always on the same server and is part of the web app, just include it. You would have to do some checking and validation to ensure that the file is there etc.
If the URL points to anywhere on the internet, insert it as an iframe.
Solution 1 (everything is local)
Assuming there is some function called getPhpFileName that returns the name of the PHP file. You need the actual name of the php file, not the url pointing to it. The file is read directly from the file system, not through the web server.
$phpFile = getPhpFileName($row['url']);
if ( file_exists($phpFile) ) {
#include $phpFile;
}
example1.php (this is the file to be included)
<div>Hello Example1</div>
Solution 2 (iframe)
In this case, the iframe is returned and the browser will be responsible for getting the output from the url and inserting it on the page.
<iframe src="<?=$row['url']?>"></iframe>
I have the following jquery statement:
$("#add").click(
function(event){
var groupName = $("#groupName option:selected").text();
var studentsToAdd = $('select#mainList').val();
var mode = "exempt";
$.post(
"addToList.php",
{ studentsToAdd: studentsToAdd, mode: mode },
function(data) {
$('#groupList').html(data[exemptList]);
$('#mainList').html(data[nonexemptList]);
}
);
});
With the following php code:
$studentsToAdd = $_REQUEST['studentsToAdd'];
$arrayLength = count($studentsToAdd);
$exemptList = "";
$nonexemptList = "";
for ($i=0;$i<$arrayLength;$i++){
$result = mysql_query("UPDATE students SET exempt=1 WHERE id = '$studentsToAdd[$i]'");
}
$result = mysql_query("SELECT * from students WHERE exempt = 1");
while($row = mysql_fetch_array($result))
{
$exemptList = $exemptList . "<option value=\"" . $row['id'] . "\">" . $row['last'] . ", " . $row['first'] . "</option>";
}
$result = mysql_query("SELECT * from students WHERE exempt = 0");
while($row = mysql_fetch_array($result))
{
$nonexemptList = $nonexemptList . "<option value=\"" . $row['id'] . "\">" . $row['last'] . ", " . $row['first'] . "</option>";
}
$data = array(
'exemptList' => $exemptList,
'nonexemptList' => $nonexemptList
);
echo json_encode($data);
I am trying to update both mainList and exemptList select elements with the single jQuery .post. It is not working. Thoughts?
If your php code is in another page or in a function, which you haven't mentioned, return $data instead of return json_encode($data) should work and leave it as an array. Otherwise you are getting a json string back, from json_encode(), which you need to parse into a javascript object, so try:
var decoded = $.parseJSON(data);
$('#groupList').html(decoded.exemptList);
$('#mainList').html(decoded.nonexemptList);
At least from what i can tell at first glance and 11 pm.
Edit: You can always try console.log(data) with Firefox Firebug plugin and see what you are getting from the server and then see if you need to decode what you are getting, change how you write the array or quotes or whatever.
A possible solution is to decode the JSON object when it is returned. Additionally, the stuff inside the [] needs to have quotes around it:
function(data) {
var json = JSON.parse(data);
$('#groupList').html(json["exemptList"]);
$('#mainList').html(json["nonexemptList"]);
}
Also, maybe try $.ajax, and set dataType to json (even though the default is intelligent guess, which should work anyway since the PHP is sending a JSON object.)
Maybe you could try:
function(data) {
$('#groupList').html(data["exemptList"]);
$('#mainList').html(data["nonexemptList"]);
}
exemptList and nonexemptList were probably treated as variables instead of names.
I'm building a site that will (eventually) be the front-end for a game. I want to be able to dynamically build a list of "powers" that the user is able to purchase. In order to build these lists, I'm using a PHP-based SQL query, then passing it to Javascript for dynamic choices (some powers have prerequisite powers).
I know there's a simpler way to do what I'm doing, but I'm not super concerned with that right now (I will be later, but I'm trying to get this functional and then clean) (again, I know this is non-optimal).
I'm using eval to parse which divs to show, and I want to know how not to.
I'm having issues getting my div names built right in the first place.
Here's my code:
Javascript (separate file)
function upgradeList(passed)
{
var PowerArray = [];
var DetailPowerID = [];
var EscapedPowerID = [];
PowerArray.push([]);
PowerArray = eval(passed);
var OutputThing="";
for (i=0;i<PowerArray.length;i++)
{
DetailPowerID[i] = 'detail' + PowerArray[i][0];
EscapedPowerID[i] = "'" + DetailPowerID[i] + "'";
}
for (i=0;i<PowerArray.length;i++)
{
OutputThing = OutputThing + "<br><a href='#' onClick='showUpgradeDetails(" + DetailPowerID[i] + ")'>" + PowerArray[i][2] + "</a><div class='hidden' id='" +
DetailPowerID[i] + "'>" + PowerArray[i][3] + "</div>"; }
document.getElementById("secondUpgrade").innerHTML=OutputThing;
document.getElementById("secondUpgrade").style.display='block';
}
}
PHP writing HTML and JS:
{$AbleToUpgrade and $UpgradeList are both 2d arrays built from SQL queries)
echo "<script name='UpgradeList'>";
settype($UpgradesListSize[$i],"int");
for ($i=0;$i<count($AbleToUpgrade);$i++)
{
echo "var UpgradeList" . $AbleToUpgrade[$i][0] . " = new Array();";
for ($j=0;$j<=$UpgradesListSize[$i];$j++)
{
echo "UpgradeList" . $AbleToUpgrade[$i][0] . ".push(Array('"
. $UpgradeList[$i][$j][0] . "', '"
. $UpgradeList[$i][$j][1] . "', '"
. $UpgradeList[$i][$j][2] . "', '"
. $UpgradeList[$i][$j][3] . "', '"
. $UpgradeList[$i][$j][4] . "'));";
}
}
echo "</script>";
... and, later...
echo "<div id='SpendUpgrade'>
Select power to upgrade:
<ul>";
for ($i=0;$i<count($AbleToUpgrade);$i++)
{
echo "<li><a href='#' name='UpgradeList" . $AbleToUpgrade[$i][0] . "' onClick='upgradeList(this.name)'>" . $AbleToUpgrade[$i][1] . " - " . $AbleToUpgrade[$i][2] . "</a></li>";
}
echo "</select>
<div id='secondUpgrade' class='hidden'>
</div>
<div id='thirdUpgrade' class='hidden'>
</div>
</div>";
When I load the page, I wind up with generated text like this:
Real Armor
and the corresponding div:
<div class="hidden" id="detail21" style="display: none;">Your armor only works in the Waking</div>
In order to get the div to show (display:block;), I need to call the function like so:
showUpgradeDetails("detail21")
but I can't make JS / PHP write the quotes correctly. Help (with any or all of this?) please!
I found a resolution, and it wasn't JSON.parse().
I changed PowerArray = eval(passed); into PowerArray = window[passed];.
Because passed contains the name of a variable, and is not the variable itself, I couldn't work directly with it. However, because it was a string that held exclusively the name of a globally-defined variable, I could pass it to the window[] construct and have it work.
Following is an ajax post page which renders the checkboxes on run-time. I am facing issue while writting the script for select all button, when I click on the button only 1 value is getting selected not the entire array:
<?php
session_start();
error_reporting(E_ALL);
ini_set("display_errors", 1);
include("../includes/functions.php");
if(isset($_REQUEST['t']))
{
$td = $_REQUEST['t'];
$t = split(",",$td);
$all = "";
$box_in_row = 0 ;
$this_box="<table border=0><tr>";
foreach($t as $table)
{
$this_box = "<td><h3>$table</h3>";
$result = mysql_query("SHOW FULL COLUMNS FROM $table FROM prfxcom1_prfx");
$options = "";
while($r = mysql_fetch_object($result))
{
if(!empty($r->Comment))
{
$options .= "<br><input type=checkbox name=\"".$table."[]\" value='$r->Field' id=\"$table\">" . $r->Field;
}
}
if($table == "transfer_req")
{
$options .= "<br><input type=checkbox name=\"".$table."[]\" value='Net Profit' id=\"$table\">NetProfit";
}
$this_box .= $options;
// Button
$click = "$('#$table').attr('checked', 'checked')";
$button = "<br /><input style='margin-top:10px;' type='button' name='$table_button' id='$table_button' value=' Select All ' onclick=\"$click\"/>";
$all .= "<div class='tblBox'>".$this_box.$button."</div></td>";
}
//$all = "<table class=\"listing form\" cellpadding=\"0\" cellspacing=\"0\">".$all."</table>";
echo $all;
}
?>
Issue is faced in the line:
$click = "$('#$table').attr('checked', 'checked')";
Please suggest, I am stuck on this.
Thanks,
Hardik
WHAT???
$click = "$('#$table').attr('checked', 'checked')";
How can you write Javascript in the middle of a PHP file? It needs to be in script tags but even then PHP runs at the server and will not render your Javascript for you.
Add script tags, change your ID's to separate ones and give them the same class like tableClassName, and then write the following.
$(function(){
$('.tableClassName').attr('checked', 'checked')";
});
Ignoring the many issues with the code and simply answering the question:
You need to refer to the checkboxes using a class name not a ID (you have given them all the same ID)
For these lines: $options .= "<br><input type=checkbox name=\"".$table."[]\" value='$r->Field' id=\"$table\">" . $r->Field;
Change to: $options .= "<br><input type=checkbox name='" . $table . "[]' value='" . $r->Field ."' class='" . $table . "'>" . $r->Field;
For this line: $click = "$('#$table').attr('checked', 'checked')"; use single quotes or escape the $
Change to: $click = '$("."'.$table.'").attr("checked", "checked")';