I'm trying to write a php and javascript code that's going to behave similarly to the code I have below (I didn't write the code) but I'm a little confused on what's going on in the php and how the two are communicating. I've tried to watch videos and read about php but I'm still pretty confused by it.
Then the javascript makes requests to the php when its buttons are clicked and the php sends information back.
The general function of the php file is it displays the contents of a random file in the http://webster.cs.washington.edu/cse154/services/flashcards/pokemon directory. It can take in a parameter called mode. When the user passes in a mode value of categories it outputs a list of all of the folder names in http://webster.cs.washington.edu/cse154/services/flashcards. Otherwise, it just displays the contents of a random file as before.
I get it on a broad overview but I'm still kind of confused on how the php code is working. Like I said I'm trying to write a code that's going to be quite similar to this so I just am trying to get a better understanding of how php works but all the information i've read hasn't been that helpful.
<?php
# Solution to CSE 154 Flashcard lab.
# generates a JSON list of categories if passed a parameter mode
# with the value of categories. Otherwise outputs a random question
# from the passed in category in XML.
$mode = $_GET["mode"];
$category = $_GET["category"];
$url = "../../cse154/services/flashcards/";
if($mode == "categories") {
outputJson($url);
} else {
outputXml($url, $category);
}
# outputs the list of available categories in JSON
function outputJson($url) {
$files = glob($url . "*");
$json = array("categories" => array());
foreach($files as $file) {
$count = count(glob($file."/*"));
$json["categories"][basename($file)] = $count;
}
header("Content-type: application/json");
print(json_encode($json));
}
# outputs a random question about the provided category in XML
function outputXml($url, $category) {
$files = glob($url . "$category/*");
$index = array_rand($files);
// this is a great place to use list!!
list($ques, $ans) = file($files[$index]);
$dom = new DOMDocument();
$card = $dom->createElement("card");
$dom->appendChild($card);
$question = $dom->createElement("question");
$question->appendChild($dom->createTextNode($ques));
$card->appendChild($question);
$answer = $dom->createElement("answer");
$answer->appendChild($dom->createTextNode($ans));
$card->appendChild($answer);
header("Content-type: text/xml");
print($dom->saveXML());
}
?>
/* javascript */
(function() {
var category = "computerscience";
var xml = null;
// sets up onclick handlers
window.onload = function() {
document.getElementById("viewAll").onclick = viewAll;
document.getElementById("next").onclick = next;
};
// sends an ajax request to the passed in address.
// calls the passed in function when the request returns.
function ajax($adress, $function) {
var request = new XMLHttpRequest();
request.onload = $function;
request.open("GET", $adress, true);
request.send();
}
// makes a request for all of the categories.
function viewAll() {
ajax("flashcards.php?mode=categories", displayAll);
}
// displays all categories in a list on the page.
function displayAll() {
$json = JSON.parse(this.responseText);
for($cat in $json.categories) {
var li = document.createElement("li");
li.innerHTML = $cat;
li.onclick = choose;
document.getElementById("categories").appendChild(li);
}
}
// sets a new category as the category all questions should come from.
function choose() {
category = this.innerHTML;
}
// displays the next question if it was last displaying an answer or nothing.
// displays the answer to the previous question otherwise.
function next() {
if(!xml) {
ajax("flashcards.php?category=" + category, displayNext);
} else {
document.getElementById("card").innerHTML = xml.querySelector("answer").textContent;
xml = null;
}
}
// displays the question that it recieved from the server.
function displayNext() {
xml = this.responseXML;
document.getElementById("card").innerHTML = xml.querySelector("question").textContent;
}
})();
Related
On trying to return some data from a GET request via AJAX, I'm continuously greeted with this nasty error message ...Unexpected token { in JSON... and I can clearly see where it's coming from. Note that this only happens if I have more than one(1) item being returned from the database. If I only have one(1) item I am able to access it data.id, data.user_name, so on and so forth.
{
"id":"39",
"user_id":"19",
"user_name":"Brandon",
"content":"Second Post",
"date_created":"2018-01-24 21:41:15"
}/* NEEDS TO BE A ',' RIGHT HERE */ {
"id":"37",
"user_id":"19",
"user_name":"Brandon",
"content":"First",
"date_created":"2018-01-24 15:19:28"
}
But I can't figure out how to fix it. Working with data, arrays, and objects is an artform I have yet to master.
JAVASCRIPT (AJAX)
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost/mouthblog/test.php');
xhr.onload = () => {
if (xhr.status == 200) {
const data = xhr.responseText;
const jsonPrs = JSON.parse(data);
console.log(jsonPrs);
} else {
console.log('ERROR');
}
};
xhr.send();
PHP (this is where the data is coming from)
<?php
class BlogRoll extends Connection {
public function __construct() {
$this->connect();
$sql = "SELECT `id`, `user_id`, `user_name`, `content`, `date_created`
FROM `posts`
ORDER BY `date_created` DESC";
$query = $this->connect()->prepare($sql);
$result = $query->execute();
if ($result) {
while ($row = $query->fetch(PDO::FETCH_OBJ)) {
header('Content-Type: application/json;charset=UTF-8');
echo json_encode($row);
}
} else {
echo 'NO POSTS TO DISPLAY';
}
}
}
I've been at this for a couple of hours now, everything similar to my problem on SO seems to be something different and I can't really find a decent plain JavaScript tutorial on returning real data. Everyone wants to use jQuery.
The reason why your code is failing is because you are using
echo json_encode($row);
This will echo an array for every row, but it is not valid JSON. I have corrected your PHP code (note: it has not been tested)
<?php
class BlogRoll extends Connection {
public function __construct() {
$this->connect();
$sql = "SELECT `id`, `user_id`, `user_name`, `content`, `date_created`
FROM `posts`
ORDER BY `date_created` DESC";
$query = $this->connect()->prepare($sql);
$result = $query->execute();
$returnArray = array(); // Create a blank array to put our rows into
if ($result) {
while ($row = $query->fetch(PDO::FETCH_OBJ)) {
array_push($returnArray, $row); // For every row, put that into our array
}
} else {
// Send the JSON back that we didn't find any data using 'message'
$returnArray = array(
"message" => "No data was found"
);
}
header('Content-Type: application/json;charset=UTF-8'); // Setting headers is good :)
exit(json_encode($returnArray)); // Exit with our JSON. This makes sure nothing else is sent and messes up our response.
}
}
Also, you stated this:
If I only have one(1) item I am able to access it data.id, data.user_name, so on and so forth.
That is correct because the array only contains that one item. The example you would access it via data.0.id, data.1.id, data.2.id, etc as each row is in its own array.
You must print only once, e.g. a data "package" from which you will reference the items on the client-side correspondingly. But in your code you're actually printing for each row a data "package".
The solution is to create an array and save the whole fetched data into it. After that the array should be json-encoded and printed.
if ($result) {
// Save the fetched data into an array (all at once).
$fetchedData = $query->fetchAll(PDO::FETCH_ASSOC);
// Json-encode the whole array - once.
// header('Content-Type: application/json;charset=UTF-8');
echo json_encode($fetchedData);
} else {
echo 'NO POSTS TO DISPLAY';
}
I was wondering why my variable from my php page isn't saving to my .txt. I have posted the code below. All the variables match.
Everytime the new page refreshes, the message disappears and I've checked my txt file, the variables are not saved in an array as it should be.
function updateData() {
$.getJSON("#host/information.txt",
function(data) {
var senator = data[0];
var cmicrophone = data[1];
var microphone = data[2];
var words = data[3];
$("#java").text(senator + cmicrophone + microphone + words);}
);
}
<?php
session_start();
if(isset($_POST["senator"]) && isset($_POST["cmicrophone"]) && isset($_POST["microphone"]) && isset($_POST["words"])) { // If the page receives POST data, it needs to be stored
$senator = $_POST["senator"];
$cmicrophone = $_POST["cmicrophone"];
$microphone = $_POST["microphone"];
$words = $_POST["words"];
$data = json_encode(Array($senator, $cmicrophone, $microphone, $words)); // Put values into an array and encode it for storage
file_put_contents('information.txt', $data); // Put the JSON-encoded array into a text file. This function replaces the contents of the text file, which is exactly what is needed in this application. To append instead of replacing the contents, you need a FILE_APPEND flag.
} else { // If there's no POST data, the values are retrieved from the storage
$data = json_decode(file_get_contents('information.txt')); // Retrieve the contents of the text file and decode them back into an array
$senator = $data[0];
$cmicrophone = $data[1];
$microphone = $data[2];
$words = $data[3];
}
echo "". $senator. "" .$cmicrophone. "" .$microphone. "";
$wordformat = wordwrap($words, 32, "\n", false);
echo "".$words. "";
?>
If the code is correct, would it just be the
$.getJSON()
location isn't correct? The variables are all correct.
I have HTML5 table with each row consisting of name, address and reference number. Each row also has a button at the end that when the user clicks I need to capture the reference number as a javascript variable and send it to a php file to enable me to search my database using this unique reference.
The code fragments below show what happens when the button is clicked, the process() function that sends the data, and the function that creates the xmlHttp object.
The problem is that even though it captures the reference number variable successfully, it doesnt transfer it to the php file. I know the connection is ok as I have set up alerts at ready states 1,2,3,4 and 200 - all these are ok.
I know also that the variable in the php file is never set by testing it with isset().
Confused and wasting lots and lots of time :(
Thanks for looking.
var referenceNumber;
jQuery('.getrowdata').on('click', function() // called when button in html table is clicked
{
var $row = jQuery(this).closest('tr');
var $columns = $row.find('td');
var value;
jQuery.each($columns, function(i, item)
{
value = item.innerHTML;
if(i < 6)
{
selectedRowArray.push(value); // adds each element of the table to the array
}
referenceNumber = selectedRowArray[5]; // the unique ref that i need to query the dbase
}
);
createXmlHttpRequestObject(); // function given below
process(); // function given below
window.open("myphpfile.php"); /* file that will use the newly set ref number to query the dbase and display the query results */
});
function process()
{
xmlHttp.open("GET","myphpfile.php?phpref="+referenceNumber,true); /*transfer the js var to php var*/
xmlHttp.send(null);
}
function createXmlHttpRequestObject()
{
var xmlHttp;
if(window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
else
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");// the user is using IE
}
return xmlHttp;
}
/*php code below as requested*/
echo '<?xml version="1.0" encoding = "UTF-8" standalone = "yes" ?>';
$phpref;
$phpref = $_GET['phpref'];
if(isset($phpref))
{
echo $phpref;
}
else
{
echo "NOT SET!";
}
I am working on a project that uses a function I called AjaxRequest which handles all AJAX requests I make. I have no problems in making the request however getting the request back is the issue and placing it where I want it on my page is becoming stressful.
HTML BIT
<body onLoad="calling();">
<div id="status">Status: </div>
</body>
JAVASCRIPT BIT
function calling() {
var answer = ajaxRequest("testing", "test.php", "test=test");
document.getElementById("status").innerHTML += answer[1];
document.getElementById("status").innerHTML += " " + answer[3];
}
function ajaxRequest(app, location, credentials) {
var extras = "";
if(credentials === "" || credentials) {
extras = "&" + credentials;
}
var ajax = ajaxObj("POST", location);
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
var obj = JSON.parse(ajax.responseText);
var arrayObj = [];
for(var i in obj) { arrayObj.push([i, obj[i]]); }
return arrayObj;
}
}
ajax.send("app=" + app + extras);
}
there are two other functions running: ajaxObj and ajaxReturn but I excluded those because they is not the problem. Furthermore, I am trying to make ajaxRequest an efficient function that could be used by more than one application without having to rewrite all the code in more than one location. All error handling acquires before the actual use of ajaxRequest.
PHP BIT
<?php
if($_POST['app'] == "testing") {
$hey = array('success' => 1, 'message' => 'Successful');
echo json_encode($hey);
exit();
}
?>
I'm using calling as a javascript function that does all error handling, this is just basic for the whole of my project however I try to get the JSON from php and convert it to array and the issue is returning the array into calling. I try to display the information on the page yet nothing works.
I am not looking to use any JQuery for my project so I would like to exclude the use of it for this piece of code.
If you want, you could set the header before sending back the json.
header('Content-Type: application/json');
Usually you don't need it, but it will tell your javascript that it's json, and the array will be transform in a javascript object. It work with Jquery, but I assume it'll work without too
I have a JavaScript function that is being called. I need to have it call a PHP function and return a true/false.
The script with the function is in the file /db/cancel_hike.php
My current JS looks like this:
function uncancelHike( hike_id )
{
//var url = "/db/cancel_hike.php;
var success = null;
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.open("GET", url , true);
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
var xmlDoc = request.responseXML;
// obtain the array of markers and loop through it
markers = xmlDoc.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++)
{
// obtain the attribues of each marker
success = markers[i].getAttribute("success");
if ( success == "true" )
{
document.getElementById("success").style.display = 'block';
document.getElementById("warning").style.display = 'none';
document.getElementById("error").style.display = 'error';
}
if ( success == "false" )
{
document.getElementById("success").style.display = 'none';
document.getElementById("warning").style.display = 'none';
document.getElementById("error").style.display = 'block';
}
}
}
}
request.send(null);
return false;
}
What I am having trouble with is:
How to call an actual function in the PHP script?
Do I absolutely need to have some XML returned? Or is there a way to just get back the returned value?
I am using YUI JS library. Do I need to make some calls to it, or is it not necessary in this case?
How to call an actual function in the PHP script?
You can't. You request URIs.
Write a PHP script that calls the function you want and place it at the URI you call.
(You can use query strings and the like as the input to an if statement that you use to conditionally call different functions)
Do I absolutely need to have some XML returned? Or is there a way to just get back the returned value?
You can return any kind of data you like.
I am using YUI JS library. Do I need to make some calls to it, or is it not necessary in this case?
It's a library. You never need to make calls to it. It often simplifies the code you have to write.
How to call an actual function in the PHP script?
Do I absolutely need to have some XML returned? Or is there a way to just get back the returned value?
Well, you don't call the actual function. What you want to do is pass variables using GET, that is, by appending them to the URL like file_name.php?var1=this&var2=that to pass var1 of "this" and var2 equaling "that." You retrieve them in the PHP file with $_GET['this'] and $_GET['that']. Whatever PHP outputs to the page via echo, print_r, etc. is then sent back in a request object as part of its responseText property.
You just set url in request.open to a URL on your site. For example, in your .js file:
request.open("GET", "answer_me.php?hike_id=" + hike_id, true);
And in your .php file:
<?php
$hike_id = $_GET['hike_id'];
if ($hike_id < 5) {
echo "true"; // echo true would return "1", BTW
} else {
echo "false"; // echo false would return nothing
}
Note that that will just return a string value to request.responseText of false, thus you could do this:
var result = request.responseText;
if (result === "true") {
...
document.getElementById("success").style.display = "block";
...
} else {
...
document.getElementById("success").style.display = "none";
...
}
You do not need it to be XML, especially as it looks like you're not really using the loop (the same three DOM elements are being assigned values each time).
And honestly, for AJAX I'd recommend using a framework like jQuery (or YUI, although I don't find its AJAX stuff as intuitive). Your entire code would look like this:
var $success = $("#success");
var $error = $("#error");
function cancelHikeCallback(data) {
var is_success = (data === "true");
$success.toggle(is_success);
$error.toggle(!is_success);
}
function cancelHike(hikeIdToSend) {
$.get("/db/cancel_hike.php", {hike_id: hikeIdToSend}, cancelHikeCallback);
}
IMO things like jQuery's $.ajax ($.get is a specialized form of $.ajax) make this stuff much easier to read and debug.
jsFiddle Example