How to log PHP file run with jQuery AJAX in browser console? - javascript

I have a PHP file that does data processing. It's run by $.ajax(), sometimes on big files that take a long time to process. I need to log some info about the ongoing process in the browser console that is displayed on the go, not just when the PHP file has finished running.
From the research I did, I get that there are two difficulties:
Getting PHP to spit out something before it's done
Getting jQuery/JS to display it on the go
To address #1, I've tried:
echo "started"."<br>";
foreach (array("done this", "done that","had a coffee","burp") as $msg) {
sleep(3);
echo $msg."<br>";
flush();
ob_flush();
}
flush(); ob_flush(); is supposed to do the job, although as you can test here it does not strictly display ever 3s as it's expected to. Any suggestion to get it to display as expected?
As for how to address #2, I have explored a solution involving XMLHttpRequest, but I'm not familiar with the subject so not sure neither what to look for nor if it's the right direction...
Here is the test code of what I'm trying to get to run:
$("#run").click(function(e) {
$.ajax({
url: "http://constances-web-dev.vjf.inserm.fr/constances-web/ajax-test.php",
xhr: function() {
// get the native XmlHttpRequest object
var xhr = $.ajaxSettings.xhr();
xhr.addEventListener('readystatechange', function(e) {
console.log(e)
});
// set the onprogress event handler
//xhr.onprogress = function(evt){ console.log(evt.target.response) } ;
// set the onload event handler
return xhr;
},
success: function(msg) {
console.log(msg);
},
error: function(msg) {
console.log("Erreur: " + msg);
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run">go</button>
Subsidiary question: Is there an (easy) way to go around the cross-origin restriction in order to get an AJAX example to work in a SO snippet?

as a work around I've added a log to file to my write2log function
static function log2File($string, $logFileName) {
if (substr($string,0,1 ) == "\n")
exec("echo '".date('Y-m-d_H:i:s')." ".addslashes(substr($string,1))."' >> ".$logFileName,$output,$status);
else
exec("echo -n ".addslashes($string)."' >> ".$logFileName,$output,$status);
}
I can then tail -f the log to watch how things are going
but this takes ssh access to the server so
i'd still be interested in figuring out how to log to console

Related

call PHP function inside JS [duplicate]

Is there a way I can run a php function through a JS function?
something like this:
<script type="text/javascript">
function test(){
document.getElementById("php_code").innerHTML="<?php
query("hello"); ?>";
}
</script>
<a href="#" style="display:block; color:#000033; font-family:Tahoma; font-size:12px;"
onclick="test(); return false;"> test </a>
<span id="php_code"> </span>
I basically want to run the php function query("hello"), when I click on the href called "Test" which would call the php function.
This is, in essence, what AJAX is for. Your page loads, and you add an event to an element. When the user causes the event to be triggered, say by clicking something, your Javascript uses the XMLHttpRequest object to send a request to a server.
After the server responds (presumably with output), another Javascript function/event gives you a place to work with that output, including simply sticking it into the page like any other piece of HTML.
You can do it "by hand" with plain Javascript , or you can use jQuery. Depending on the size of your project and particular situation, it may be more simple to just use plain Javascript .
Plain Javascript
In this very basic example, we send a request to myAjax.php when the user clicks a link. The server will generate some content, in this case "hello world!". We will put into the HTML element with the id output.
The javascript
// handles the click event for link 1, sends the query
function getOutput() {
getRequest(
'myAjax.php', // URL for the PHP file
drawOutput, // handle successful request
drawError // handle error
);
return false;
}
// handles drawing an error message
function drawError() {
var container = document.getElementById('output');
container.innerHTML = 'Bummer: there was an error!';
}
// handles the response, adds the html
function drawOutput(responseText) {
var container = document.getElementById('output');
container.innerHTML = responseText;
}
// helper function for cross-browser request object
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
success(req.responseText) : error(req.status);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
The HTML
test
<div id="output">waiting for action</div>
The PHP
// file myAjax.php
<?php
echo 'hello world!';
?>
Try it out: http://jsfiddle.net/GRMule/m8CTk/
With a javascript library (jQuery et al)
Arguably, that is a lot of Javascript code. You can shorten that up by tightening the blocks or using more terse logic operators, of course, but there's still a lot going on there. If you plan on doing a lot of this type of thing on your project, you might be better off with a javascript library.
Using the same HTML and PHP from above, this is your entire script (with jQuery included on the page). I've tightened up the code a little to be more consistent with jQuery's general style, but you get the idea:
// handles the click event, sends the query
function getOutput() {
$.ajax({
url:'myAjax.php',
complete: function (response) {
$('#output').html(response.responseText);
},
error: function () {
$('#output').html('Bummer: there was an error!');
}
});
return false;
}
Try it out: http://jsfiddle.net/GRMule/WQXXT/
Don't rush out for jQuery just yet: adding any library is still adding hundreds or thousands of lines of code to your project just as surely as if you had written them. Inside the jQuery library file, you'll find similar code to that in the first example, plus a whole lot more. That may be a good thing, it may not. Plan, and consider your project's current size and future possibility for expansion and the target environment or platform.
If this is all you need to do, write the plain javascript once and you're done.
Documentation
AJAX on MDN - https://developer.mozilla.org/en/ajax
XMLHttpRequest on MDN - https://developer.mozilla.org/en/XMLHttpRequest
XMLHttpRequest on MSDN - http://msdn.microsoft.com/en-us/library/ie/ms535874%28v=vs.85%29.aspx
jQuery - http://jquery.com/download/
jQuery.ajax - http://api.jquery.com/jQuery.ajax/
PHP is evaluated at the server; javascript is evaluated at the client/browser, thus you can't call a PHP function from javascript directly. But you can issue an HTTP request to the server that will activate a PHP function, with AJAX.
The only way to execute PHP from JS is AJAX.
You can send data to server (for eg, GET /ajax.php?do=someFunction)
then in ajax.php you write:
function someFunction() {
echo 'Answer';
}
if ($_GET['do'] === "someFunction") {
someFunction();
}
and then, catch the answer with JS (i'm using jQuery for making AJAX requests)
Probably you'll need some format of answer. See JSON or XML, but JSON is easy to use with JavaScript. In PHP you can use function json_encode($array); which gets array as argument.
I recently published a jQuery plugin which allows you to make PHP function calls in various ways: https://github.com/Xaxis/jquery.php
Simple example usage:
// Both .end() and .data() return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
I have a way to make a Javascript call to a PHP function written on the page (client-side script). The PHP part 'to be executed' only occurs on the server-side on load or refreshing'. You avoid 'some' server-side resources. So, manipulating the DOM:
<?PHP
echo "You have executed the PHP function 'after loading o refreshing the page<br>";
echo "<i><br>The server programmatically, after accessing the command line resources on the server-side, copied the 'Old Content' from the 'text.txt' file and then changed 'Old Content' to 'New Content'. Finally sent the data to the browser.<br><br>But If you execute the PHP function n times your page always displays 'Old Content' n times, even though the file content is always 'New Content', which is demonstrated (proof 1) by running the 'cat texto.txt' command in your shell. Displaying this text on the client side proves (proof 2) that the browser executed the PHP function 'overflying' the PHP server-side instructions, and this is because the browser engine has restricted, unobtrusively, the execution of scripts on the client-side command line.<br><br>So, the server responds only by loading or refreshing the page, and after an Ajax call function or a PHP call via an HTML form. The rest happens on the client-side, presumably through some form of 'RAM-caching</i>'.<br><br>";
function myPhp(){
echo"The page says: Hello world!<br>";
echo "The page says that the Server '<b>said</b>': <br>1. ";
echo exec('echo $(cat texto.txt);echo "Hello world! (New content)" > texto.txt');echo "<br>";
echo "2. I have changed 'Old content' to '";
echo exec('echo $(cat texto.txt)');echo ".<br><br>";
echo "Proofs 1 and 2 say that if you want to make a new request to the server, you can do: 1. reload the page, 2. refresh the page, 3. make a call through an HTML form and PHP code, or 4. do a call through Ajax.<br><br>";
}
?>
<div id="mainx"></div>
<script>
function callPhp(){
var tagDiv1 = document.createElement("div");
tagDiv1.id = 'contentx';
tagDiv1.innerHTML = "<?php myPhp(); ?>";
document.getElementById("mainx").appendChild(tagDiv1);
}
</script>
<input type="button" value="CallPHP" onclick="callPhp()">
Note: The texto.txt file has the content 'Hello world! (Old content).
The 'fact' is that whenever I click the 'CallPhp' button I get the message 'Hello world!' printed on my page. Therefore, a server-side script is not always required to execute a PHP function via Javascript.
But the execution of the bash commands only happens while the page is loading or refreshing, never because of that kind of Javascript apparent-call raised before. Once the page is loaded, the execution of bash scripts requires a true-call (PHP, Ajax) to a server-side PHP resource.
So, If you don't want the user to know what commands are running on the server:
You 'should' use the execution of the commands indirectly through a PHP script on the server-side (PHP-form, or Ajax on the client-side).
Otherwise:
If the output of commands on the server-side is not delayed:
You 'can' use the execution of the commands directly from the page (less 'cognitive' resources—less PHP and more Bash—and less code, less time, usually easier, and more comfortable if you know the bash language).
Otherwise:
You 'must' use Ajax.

Eternal Ajax Returns Nothing, No PHP/Javascript errors, syntax or otherwise

Note: I am aware that json/jquery appears to be the preferred way of doing things at the moment. Nevertheless, I am using just plain old ajax without json/jquery.
I have set my website up so that there are no php calls in the index page. Instead, I load scripts which handle most link clicks via ajax calls back to the server. Theoretically, the server returns the response text, and then the javascript on readystatechange function (set to ajax_response()) inserts the response text directly into the div container with id="innercontent".
Here is the code for my main javascript file:
function ajax()
{
try{ var request = new XMLHttpRequest()}
catch(e1){
try{ request = new ActiveXObject("Msxml2.XMLHTTP") }
catch(e2){
try{ request = new ActiveXObject("Microsoft.XMLHTTP") }
catch(e3){ request = false }
}
} return request
}
function ajax_response()
{
if(this.readyState == 4){
if(this.status == 200){
if(this.responseText != null){
document.getElementById('innercontent').innerHTML = this.responseText
} else alert("Ajax error: No data received")
} else alert("Ajax error: " + this.statusText)
}
}
function fetch_document(opcode)
{
params = "opcode=" + opcode
request = new ajax();
request.open("POST", "/site-php/fetch_document.php", true)
// request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
// request.setRequestHeader("Content-length", params.length)
request.setRequestHeader("Connection", "close")
request.onreadystatechange = ajax_response()
request.send(params)
}
function fetch_comic(series, page_number)
{
params = "series=" + series + "&page_number=" + page_number
request = new ajax();
request.open("POST", "/site-php/fetch_comic.php", true)
// request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
// request.setRequestHeader("Content-length", params.length)
request.setRequestHeader("Connection", "close")
request.onreadystatechange = ajax_response()
request.send(params)
}
There doesn't appear to be any syntax errors in the javascript, so I thought maybe that the problem was on the server side. But no errors are logged in /var/log/error_log.
Here is the code for my php functions:
<?php
require_once "kolodruid.php";
require_once "login.php";
if(isset($_POST['series']) && isset($_POST['page_number'])){
$series = $_POST['series'];
$page_number = $_POST['page_number'];
}
$mysql_db = mysql_connect($mysql_host, $mysql_user, $mysql_pass);
mysql_select_db("webcomics");
mysql_close($mysql_db);
$fd = $docroot . "test.html";
$msg = file_get_contents($fd);
echo $msg;
?>
Note that the actual functionality of this function is to fetch webcomic information from a database. In the process of trying to figure out what has gone wrong, however, I ended up simplifying the function to try to see if just a simple echo statement would work.
also:
<?php
require_once "kolodruid.php";
$opcode = $_POST['opcode'];
switch($opcode){
case "ABOUT":
echo file_get_contents("about.html");
break;
default:
echo file_get_contents("whoops.html");
break;
}
?>
When I look at the firefox console network tab, clicking on the links "webcomic" generates green lights all the way. I check to see if the parameters tab has any data, and it does. The response tab, however, doesn't contain anything.
I've checked that all the files are reachable and in places that the server has access to. I also took out the setrequestheader() functions in the javascript, as it seems that was causing a fatal error. I then re-enabld the close connection setrequestheader() to see if maybe I actually still had to set that one manually. It seems that it didn't generate a fatal error, so I didn't comment it back out.
I've checked the php code for syntax errors, and also checked the javascript code for syntax errors. Both come out clean. I've restarted my server several times (it's localhost), and have also restarted my mysql database server out of desperation.
At this point, the whole enterprise had devolved into just making minor edits in the desperate hope that SOMETHING gives a clue as to what is going on. I have changed the asynchronous calls to synchronous calls to see if that maybe was the problem, but to no avail. (Thus, I rechanged them back to asynchronous calls).
I feel like it's something really stupid and/or obvious, but I've been pouring over the code for hours, and am afraid I can't see the forest for the trees by now. Please help!
Thank you for reading this. I'm aware that Javascript questions are pretty common, but I've been reading question and answer sites for hours, too. D:
In case it matters, I'm using Apache version 2.4.6
Thank you for you help!
It turned out to be something mind-blowingly obvious after all. I was calling the function ajax_response() and assigning the value to onreadystatechange. Removing the parenthesis after ajax_response produced the desired behavior.

Ajax call via POST not working

I have a lil problem with an AJAX request.
We have a lil PHP, JavaScript application (Website). The application is running fine on all desktop browsers + on our old MDE's (some Windows CE6 MDE). Now on our new Motorola MC9200 (Windows Embedded Compact 7 formerly CE7) it's not working anymore.
The problem is some small JavaScript function. It disables the buttons/input fields, starts a Ajax.Request (prototype 1.72 but I tested jQuery 1.11.1 too), does something on the database and when everything went right it is refreshing the site via window.location. This function isn't working always on the new devices. Sometimes it does, sometimes not.
simplified code:
function loadSite(siteName) {
disableForm();
var parameters = {
/* SOME PARAMETERS */
};
new Ajax.Request('ajax/ajax_db_execute.php', {
method: 'post',
parameters: parameters,
onSuccess: callbackFunc
});
}
function callbackFunc(transport) {
response = transport.responseText.evalJSON(true);
if(response.retcode === 0) {
window.location = "start.php?id=<?php echo $id; ?>";
} else {
show_error_box(response.errortext);
enableForm();
}
}
I tried to output the response in the callbackFunc but that function wasn't even called. Next thing I tried was to put some alert at the end of the loadSite function, it was fired everytime. I already checked the parameters and they look fine too.
After that I put some simple fwrite in the php file. It looks like that file isn't even called sometimes. So the question is why?
By changing the method to 'get' I couldn't reproduce the problem and everything is working fine. Problem about that is that I don't want to use get + some parameters might be too long for get to handle.
The parameters in that example were just some simple integers and strings. Does anyone have an idea what might cause the problem and some workaround?
It seems that your post request response is not synchronized. So please use setTimeout function in your post callback like that
setTimeout(function(transport) {
response = transport.responseText.evalJSON(true);
if(response.retcode === 0) {
window.location = "start.php?id=<?php echo $id; ?>";
}
else
{
show_error_box(response.errortext);
enableForm();
}
}, 3000);

How to include JSON data in javascript synchronously without parsing?

I want to load a JSON file from my own server containing an array into a javascript Object variable.
I would like to do it at the beginning of page load in a synchronous way because data is needed during page load.
I managed to use jQuery.getJSON but this is asynch ajax and it seems a little overkill.
Is there a way to load JSON in a synch way without doing your own parsing? (more or less like using a <script language="JavaScript" src="MyArray.json"></script>)
Thanks in advance for any help, hope it makes sense since I am a javascript newbie.
Paolo
getJSON() is simply shorthand for the ajax() function with the dataType:'json' set. The ajax() function will let you customize a lot about the request.
$.ajax({
url: 'MyArray.json',
async: false,
dataType: 'json',
success: function (response) {
// do stuff with response.
}
});
You still use a callback with async:false but it fires before it execution continues on from the ajax call.
Here you go:
// Load JSON text from server hosted file and return JSON parsed object
function loadJSON(filePath) {
// Load json file;
var json = loadTextFileAjaxSync(filePath, "application/json");
// Parse json
return JSON.parse(json);
}
// Load text with Ajax synchronously: takes path to file and optional MIME type
function loadTextFileAjaxSync(filePath, mimeType)
{
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET",filePath,false);
if (mimeType != null) {
if (xmlhttp.overrideMimeType) {
xmlhttp.overrideMimeType(mimeType);
}
}
xmlhttp.send();
if (xmlhttp.status==200 && xmlhttp.readyState == 4 )
{
return xmlhttp.responseText;
}
else {
// TODO Throw exception
return null;
}
}
NOTE: This code works in modern browsers only - IE8, FF, Chrome, Opera, Safari. For obosolete IE versions you must use ActiveX, let me know if you want that I will tell you how ;)
if you're using a server script of some sort, you could print the data to a script tag on the page:
<script type="text/javascript">
var settings = <?php echo $json; ?>;
</script>
This will allow you to use your data synchronously rather than trying to use AJAX asynchronously.
Otherwise you'll have to wait for the AJAX callback before continuing on with whatever it is you're doing.
I only needed to read a small input file provided in json format and extract a small amount of data. This worked just fine in the circumstances:
json file is in the same directory as the script and is called data.json, it looks something like this:
{"outlets":[
{
"name":"John Smith",
"address":"some street, some town",
"type":"restaurant"
},
..etc...
read the data into js like this:
var data = <?php echo require_once('data.json'); ?>;
Access the data items like this:
for (var i in data.outlets) {
var name = data.outlets[i].name;
... do some other stuff...
}
If RequireJS is an option, you can make it a dependency using requirejs. I use it to mock data in my Angular application. It's essential that some of the mocked data is there before the bootstrap of the app.
//Inside file my/shirt.js:
define({
color: "black",
size: "unisize"
});
Just wrap the json data in a define and declare it as a dependency. More info here: http://requirejs.org/docs/api.html#defsimple
AFAIK jQuery has deprecated synchronous XHR requests because of the potential for performance issues. You could try wrapping your app code up in the XHR response handler as in the following:
$(document).ready(function() {
$.get('/path/to/json/resource', function(response) {
//'response' now contains your data
//your app code goes here
//...
});
});
The modern HTML5 way without jQuery would be:
var url="https://api.myjson.com/bins/1hk8lu" || "my.json"
var ok=await fetch(url)
var json=await ok.json()
alert(a.test)

MooTools JSON request

Trying to get a very simple request working with MooTools Request.JSON. After having no success building it from scratch, I took an example from somewhere and slowly pared it down to the bare, bare minimum, then put it back into my own page. The only things changed are the url and element ID, but to no avail.
Any help, ideas, will be greatly appreciated.
json.php
<?php
$result['name'] = 'yay';
header('Content-type: application/json');
echo json_encode($result);
?>
demo.js (snippet inside window.addEvent('domready', function() { )
$(document.body).getElement('input[id=game_name]').addEvents({
'keydown' : function(){
alert('hmm'); //this fires
var jsonRequest = new Request.JSON({
url: "json.php",
onComplete: function(result){ //changing to onSuccess kills everything afterwards
alert('result.name'); //this fires
alert(result.name); //this does not fire
alert('result.name'); //this does not fire
}
}).get();
}
});
PS. in neither my page, or the pared down example pages, can i get the request to send on domready, only inside an event. why is that?
thanks again
As it turns out, the problem was that I had accidentally loaded a synced duplicate file into my browser that was therefore (obviously) unable to execute anything server side.
Thank you very much for your help.
Several suggestions/questions:
Are you getting any errors in your web browser's console? Which web browser are you using? The fact that the third alert doesn't fire at all suggests that alert(result.name); is throwing an error, in which case, all further execution will be stopped and an error will appear on your browser's console.
When you say "changing to onSuccess kills everything afterwards", what exactly do you mean? Does code further down (i.e. code that's not included in the above code snippet) never execute? Or does onSuccess just never fire?
Is json.php in the same directory as the page where this script is running? Try replacing json.php in url: "json.php" with an absolute URL (/mydirectory/json.php or http://www.mywebsite.com/mydirectory/json.php) and see whether this works.
If it's any help, the following code results in an alert reading "yay" (running on a local server; json.php is a file containing the PHP code in your question):
var jsonRequest = new Request.JSON({
url: "json.php",
onSuccess: function(result) {
alert(result.name);
}
}).get();
you can find a great tutorial here
http://net.tutsplus.com/tutorials/javascript-ajax/checking-username-availability-with-mootools-and-request-json/
Exactly the same problem here.
I solved it by decoding the JSON string, which is given as parameter (instead of the expected object).
onSuccess: function(jsonString) {
console.log(JSON.decode(jsonString));
}
Here ist the documentation:
http://mootools.net/docs/core/Utilities/JSON#JSON:decode

Categories