I have ran into a strange behavior of passing JSON from PHP to jQuery.
I have some articles (Drupal CMS articles) and I need to push them into the environment.
First solution worked, while the articles was pushed directly by PHP on page load. But as my work works with more than one CMS, it takes too much time to load them all, so I need to use ajax to load one specific project at time.
now, jquery looks like this:
function doLoadArticles() {
for (var i = 0; i< projectdata[1].length; i++){
$.ajax({
data: {ip:projectdata[0]["ip"], login:projectdata[0]["login"], pass:projectdata[0]["pass"], db:projectdata[0]["db"], datatype:projectdata[1][i], aj:"aj", fc:"doLoadArticles"},
type: "post",
url: "dataFunnel.php",
success: function(data){
console.log(data);
//console.log(jQuery.parseJSON( data )) ;
}
});
}
}
Then, on PHP side is this code:
function doLoadArticles(){
$projdata;
$conn = new mysqli($_POST['ip'], $_POST['login'], $_POST['pass'], $_POST['db']);
// Check connection
if ($conn->connect_error) {
die("<div style='position:absolute; top:0;left:0; background:white;'>Connection failed: " . $conn->connect_error." <br><br>Plese try reload the page</div>");
break;
}
else{}
$sql = "Select node_revision.title, node_revision.nid, node.language, field_revision_body.body_value, field_revision_body.bundle, node_revision.timestamp
from field_revision_body
LEFT JOIN node_revision ON field_revision_body.revision_id=node_revision.vid
LEFT JOIN node ON field_revision_body.revision_id=node.vid
where field_revision_body.bundle='".$_POST['datatype']."' AND node_revision.status=1 AND node.language='cs'
ORDER BY field_revision_body.revision_id DESC LIMIT 10";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// error_log("true");
// output data of each row
$j =0;
while($row_a = $result->fetch_assoc()) {
$projdata[$j]["title"] = $row_a["title"] ;
$projdata[$j]["timestamp"] = $row_a["timestamp"] ;
$projdata[$j]["bundle"] = $row_a["bundle"] ;
$projdata[$j]["body_value"] = $row_a["body_value"];
$projdata[$j]["nid"] = $row_a["nid"];
$projdata[$j]["language"] = $row_a["language"];
$j++;
}
}
echo json_encode($projdata);
}
The problem is, that the data are there, only the passing itself does not work .. (probably because of some buged conversion?)
if I do
echo print_r($projdata);
it will pass the data, but not in usable way (ignore the broken chars, that is another not related problem, the data are thare, that is what matters)
However, as it is clear, I need it in form that I can work with, so I need json.
But if I use
echo json_encode($projdata);
it will pass some "broken nothing"
So is there any my mistake I am not aware of, or it is really some kind of bug in PHP implementation?
(by the way, I run on PHP 5.6 on MS IIS7)
Or any other way possible, how to load data dynamically without the json conversion?
Thanks in advance
Related
The overall goal is to relay information from a mysql server via a php file to the webpage being viewed. More specifically I want to target certain aspects of the php file, or certain tables in the database, and display them in different divs on the webpage. Given my limited experience I'm not sure how best to do this but I would imagine the flow would be something like this...
(I apologize for the limited code detail but everything I tried didn't seem like the right approach so I'll keep it broad so it can be open to suggestions.)
Call php file and request certain variables such as:
$(document).ready(function(){
//call sqlrelay.php
//ask for some variable ($row) or some section of the code (within the if statement)
//display it in div ('#collapseOne')
};
Listen with the php file (sqlrelay.php) such as:
<?php
//if request received from client side do this:
include ("connection.php");
$sendtable = "SELECT timein FROM timestamp1 ORDER BY id DESC LIMIT 1";
$result=mysqli_query($link, $sendtable);
$row = mysqli_fetch_array($result);
$table = $row['timein'];
echo $table;
<?
Look the API: http://api.jquery.com/jquery.ajax/
or use my code.
$(document).ready(function() {
$.ajax({
method: "POST",
url: "sqlrelay.php",
data: {
row: "your query"
},
success: function(data) {
$('#collapseOne').html(data);
}
});
});
and your PHP looks like this to catch the row request
<?php
$row = $_POST['row'];
echo $row;
-Issue Still Unresolved-
I'm trying to call a database, put all the rows of a table in an array, pass that table to my JS as json data, and then use that data as parameters for a function.
When I run the script nothing happens. I don't get any errors in the console, the rest of the script loads normally. I'm pretty new to mySQL and PHP, what am I doing wrong here? I suspect that I goofed up the php somehow.
XAMPP server, being tested on my desktop
all linked files are in the same directory
There are no visible errors displayed anywhere. As far as I can tell, the script doesn't even try to load the PHP to begin with, but also doesn't display an error in firebug's console
Attempted:
Renaming the table without spaces
placing the for loop inside the callback function
amending php errors
Here's the updated JS I'm using:
this.taskMenu = function()
{
var table = [];
$.getJSON("taskMaster.php", {"table" : "firstlist"},
function(data)
{
table.push(data);
for(i=0; i<table.length; i++)
{
var taskId = table[i].taskName.replace(/\s+/g,"") + i;
formatTask("interface",taskId,table[i].taskName,table[i].taskDescription,table[i].taskComplete);
}
});
}
and here's the updated PHP:
error_reporting(E_ALL); ini_set('display_errors','On');
$con = mysql_connect("localhost", "root", "m3648y73");
if (!$con){die('Could not connect: ' . mysql_error());};
mysql_select_db("tasklistdb", $con);
$table = $_GET['table'];
$sql = mysql_query("SELECT taskName, taskId, taskDescription, taskComplete FROM `".$table."`");
$listTasks = array();
while ($row_user = mysql_fetch_assoc($sql))
$listTasks[] = $row_user;
echo json_encode($listTasks);
mysql_close($con);
Am I linking to the DB correctly?
getJSON is asynchronous call. So before it could fetch values from PHP and execute the callback function, it moves to the for loop and here table is empty.
Solution: shift your for loop inside the callback function
You are missing a semi colon on the line $listTasks = array() in the php file
This happens because js-code after async request executed earlier than request itself is over. Try this:
this.taskMenu = function()
{
var table = [];
$.getJSON("taskMaster.php", {table : "first list"},
function(data)
{
table.push(data);
for(i=0; i<table.length; i++)
{
var taskId = table[i].taskName.replace(/\s+/g,"") + i;
formatTask("interface",taskId,table[i].taskName,table[i].taskDescription,table[i].taskComplete);
}
});
}
Your table name can't be 'first list'
You can't have a space in a MySQL table name.
Also you should put put table in the JSON value in double-quotes like {"table":"table_name"}
What I'm trying to do is create a slideshow by grabbing database information and putting it into a javascript array. I am currently using the jquery ajax function to call information from a separate php file. Here is my php code:
mysql_connect('x', 'x', 'x') or die('Not Connecting');
mysql_select_db('x') or die ('No Database Selected');
$i = 0;
$sql = mysql_query("SELECT comicname FROM comics ORDER BY upldate ASC");
while($row = mysql_fetch_array($sql, MYSQL_ASSOC)) {
echo "comics[" .$i. "]='comics/" .$row['comicname']. "';";
$i++;
}
What I want is to create the array in php from the mysql query and then be able to reference it with javascript in order to build a simple slideshow script. Please let me know if you have any questions or suggestions.
Ok have your .php echo json_encode('name of your php array');
Then on the javascript side your ajax should look something like this:
$.ajax({
data: "query string to send to your php file if you need it",
url: "youphpfile.php",
datatype: "json",
success: function(data, textStatus, xhr) {
data = JSON.parse(xhr.responseText);
for (i=0; i<data.length; i++) {
alert(data[i]); //this should tell you if your pulling the right information in
}
});
maybe replace data.length by 3 or something if you have alot of data...if your getting the right data use a yourJSArray.push(data[i]); I'm sure there's a more direct way actually...
You may want to fetch all rows into a large array and then encode it as a JSON:
$ret = array();
while($row = mysql_fetch_array($sql, MYSQL_ASSOC))
$ret[] = $row
echo json_encode($ret);
Then, on the client side, call something like this:
function mycallback(data)
{
console.log(data[0].comicname); // outputs the first returned comicname
}
$.ajax
(
{
url: 'myscript.php',
dataType: 'json',
success: mycallback
}
);
Upon successful request completion, mycallback will be called and passed an array of maps, each map representing a record from your resultset.
It's a little hard to tell from your question, but it sounds like:
You are making an AJAX call to your server in JS
Your server (using PHP) responds with the results
When the results come back jQuery invokes the callback you passed to it ...
And you're lost at this point? ie. the point of putting those AJAX results in to an array so that your slideshow can use them?
If so, the solution is very simple: inside your AJAX callback, put the results in to a global variable (eg. window.myResults = resultsFromAjax;) and then reference that variable when you want to start the slideshow.
However, since timing will probably be an issue, what might make more sense is to actually start your slideshow from within your callback instead. As an added bonus, that approach doesn't require a global variable.
If this isn't where you are stuck, please post more info.
I hope this problem is very simple, I can't figure out the solution myself it seems. Been trying and googling for hours, driving me nuts :) Ok, so I have a drag'n'drop + sortable (using scriptaculous and prototype for your information) on my index.php. I use this code to send the items dropped in a div using this code:
<script type="text/javascript">
//<![CDATA[
document.observe('dom:loaded', function() {
var changeEffect;
Sortable.create("selectedSetupTop", {containment: ['listStr', 'selectedSetupTop'], tag:'img', overlap:'vertical', constraint:false, dropOnEmpty: true,
onChange: function(item) {
var list = Sortable.options(item).element;
$('changeNotification').update(Sortable.serialize(list).escapeHTML());
if(changeEffect) changeEffect.cancel();
changeEffect = new Effect.Highlight('changeNotification', {restoreColor:"transparent" });
},
onUpdate: function(list) {
new Ajax.Request("script.php", {
method: "post",
parameters: { data: Sortable.serialize(list), container: list.id }
onLoading: function(){$('activityIndicator').show(), $('activityIndicator2').hide()},
onLoaded: function(){$('activityIndicator').hide(), $('activityIndicator2').show()},
});
}
});
});
// ]]>
</script>
I've been using this code before so I "kind of know" it will send me data to my script.php page. selectedSetupTop is my div containing the elements. Don't mind about the notification and the activityIndicator thingy. My script.php page looks like this for the moment:
parse_str($_POST['data']);
for ($i = 0; $i < count($selectedSetupTop); $i++) {
$test .= $selectedSetupTop[$i];
}
echo "<script>alert('$test');</script>";
I can't seem to get any output in the alert message, it's just blank. The purpose of the script.php is to update a row in a database and it will look kind of like this:
$sql = mysql_query("UPDATE table SET row = '$arrayInStringFormat' WHERE id = '1'") or die(mysql_error());
where the $arrayInStringFormat is a conversion of the array $selectedSetupTop to the format (1, 2, 3, 4). I guess I'll solve that using implode or something, but the problem is parsing the array $selectedSetupTop. I'm not it passes between the pages at all, really appreciate help! Tell me if I need to explain further.
Thanks in advance!
''''''
EDIT 1
If it will help, I used this code before that I know will send me the data and use it. Notice I don't wanna do my task like the way I do below:
$querySetup = $_GET["s"];
parse_str($_POST['data']);
for ($i = 0; $i < count($selectedSetupTop); $i++) {
$sql = mysql_query("UPDATE " . $querySetup . " SET orderId = $i, hero_selected = 'n' WHERE imageId = $selectedSetupTop[$i]") or die(mysql_error());
}
''''''
EDIT 2
So it does parse, but I still have the problem I can't print it. I wanna implode the array somehow.
Not sure how AJAX works in Scriptalicious/Prototype, but you don't seem to be getting the data from the AJAX call. In jQuery it would be something like this where the data you receive from the script is returned as the argument of the function.
onLoaded: function(msg){
$('activityIndicator').hide(),
$('activityIndicator2').show(),
alert(msg)
}
Secondly, you can't echo a PHP array, you have to encode it to JSON:
echo json_encode($test);
I've got a page that seems to be in full working order, but I'm having major performance issues (think 30 second delay occasionally from these calls) from what I assume is throwing too many individual POST requests to the server.
Am I right in thinking that there's some way of doing it all in one call and that doing so would improve performance, and what's the easiest way of doing it? Perhaps my use of eval() is part of the problem - or maybe my webhost is just shit.
function startCheckAchs(){
//hide the loading alert
$(document).ajaxStop(function(){
$(this).unbind("ajaxStop");
popup('loadingAlert');
});
//load lifeTimeBaked
lifeTimeBaked = loadAch("lifetimebaked");
loadAch("ach_started", "#achStarted", "achstarted");
loadAch("ach_round1", "#achRound1", "achround1");
loadAch("ach_round2", "#achRound2", "achround2");
loadAch("ach_round3", "#achRound3", "achround3");
if( rewards == 1) {
loadAch("ach_baked100", "#achBaked100", "achbaked100");
loadAch("ach_baked500", "#achBaked500", "achbaked500");
loadAch("ach_baked1000", "#achBaked1000", "achbaked1000");
loadAch("ach_nobread", "#achNoBread", "achnobread");
loadAch("ach_nodough", "#achNoDough", "achnodough");
loadAch("ach_noflour", "#achNoFlour", "achnoflour");
loadAch("ach_allach", "#achAllAch", "achallach");
}
}
function loadAch(ach, achDiv, achVar){
$.ajax({
type: "POST",
url: "scripts/loadach.php",
data: {"achievement" : ach},
dataType: "text",
success: function(result){
if ( achDiv && achVar && result == 1){
$(achDiv).show();
eval(achVar + " = 1");
return result;
} else {
return result;
}
}
});
}
Loadach.php:
$achievement=trim($_POST['achievement']);
$user = $_SESSION['userid'];
$query = "SELECT $achievement FROM breadusers WHERE userid='$user'";
$link =#mysql_query($query);
if(!$link){
die('Could not query:' . mysql_error());
}
echo mysql_result($link, 0);
?>
You are currently loading achievements individually, while you should be doing something like:
<?php
$query = "SELECT ach_started, ach_round1 FROM breadusers WHERE userid='$user'";
$link = mysql_query($query);
$results = mysql_fetch_assoc($link);
echo json_encode($results);
?>
Then, in your javascript code, parse the JSON response (setting dataType: "json" should work), loop over the returned object (has keys such as ach_started, ach_round1, etc etc), and show/hide divs as needed.
Unfortunately you are going to have to redesign that.
SQL queries are slow.
Lots of requests make things slow.
See if you can group all of the data for a user in your database. That way you can make one select for all of the data you need.
You could use a multi-dimensional array and fill it with the data needed, send the array with ajax to the php code, and then you could loop through the array in the php code and echo back the desired results.
This way you would only be making 1 ajax call each time but still get the same results. might be faster this way but i have not tested this. =)
Most browsers have a limit on the number of concurrent server requests they can handle.
If you're using sessions, you'll also find that the server can only process a single request for each session at a time, because the session file is locked by each request, and subsequent requests must wait for it to be unlocked either when the first request finishes, or when a session_write_close() is issued by the executing request.