Set $_SESSION in ajax request - php

I have this Jquery Ajax function to login in a web page.
url="<?php echo Yii::app()->createUrl("security/login") ?>"
$.ajax({
type:"POST",
url:url,
data:{},
success: function (jsonResponse) {
var json=JSON.parse(jsonResponse);
if(json.result == "SUCCESS")
{
<?php $_SESSION['LOGGED_USER']="USER"; ?>
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
And in my views layout I have this
session_start();
if( isset($_SESSION['LOGGED_USER']) )
{
print_r("LOGGED");
}
else
{
print_r("NOT LOGGED");
}
When I enter for the first time to the page It prints "NOT LOGGED" but it seems that it sets automatically the session so that when I reload the page It prints "LOGGED".
How can I set my session correctly in my ajax request?
Thank you very much :)

It seems a lot of people are confused about client vs server when it comes to Ajax. Let me see if i can clear that up:
Your JS runs in the browser (client). PHP runs on the server. The two are different languages that run on entirely different machines; they don't share the same variables or anything. They do not talk directly to each other, or really even know anything about each other. Their sole means of communication is via HTTP requests. (Well, there's WebSockets too...but that's a bit advanced yet.)
JS and PHP typically do not even run at the same time. Depending on your setup and where this script lives, one of two things is happening, and in this case, neither one is what you want.
The JS is in a file of some type the server doesn't feed to PHP. The PHP code is still in the file when the browser sees it -- and being invalid JS, causes a syntax error when you try to run it. Probably before you even get to do the Ajax post.
The JS is in a file of some type the server does feed to PHP. The PHP interpreter dutifully goes through the file, finds all the PHP code in it, and parses and runs it. The PHP code in it runs on the server, possibly before the page is even sent to the browser. (And since PHP doesn't speak JS, and doesn't even care if what it generates is valid HTML or JS...any non-PHP code in the page is irrelevant.) Anyway, by the time the browser runs your script above, it looks like this:
...
success: function (jsonResponse) {
var json=JSON.parse(jsonResponse);
if(json.result == "SUCCESS")
{
}
},
...
because PHP has already gone through the file and interpreted the bit about setting $_SESSION['LOGGED_USER']. If the user has an active session at all, logged in or not, that LOGGED_USER variable is set the second his browser requests that page.
The PHP script that's handling requests for security/login needs to set the session variable. Your JS won't be able to do it, as the session data is entirely server-side, and you can't let the browser just up and tell the server to run arbitrary PHP code without opening up a massive security hole. (Picture what could happen if the browser could say "hey, PHP, run this". All i'd have to do is pop up a JS console, see how you're doing it...and at the very least, i could write a line of JS in the console to set that variable whether i'm logged in or not.)
Or, if you really wanted, you could create another page that the JS posts to, that sets the session data. That seems a waste, though...and it might be quite difficult to do securely. (If PHP doesn't already know you're logged in, you'd have to re-authenticate and all that.) I wouldn't consider it unless for some reason security/login can't be modified.

Related

Web application is suspended (hanging up) while php curl_multi_exec is running [duplicate]

I have problem with two simultaneous AJAX requests running. I have a PHP script which is exporting data to XSLX. This operation take a lot of time, so I'm trying to show progress to the user. I'm using AJAX and database approach. Actually, I'm pretty sure it used to work but I can't figure out why, it's no longer working in any browser. Did something change in new browsers?
$(document).ready(function() {
$("#progressbar").progressbar();
$.ajax({
type: "POST",
url: "{$BASE_URL}/export/project/ajaxExport",
data: "type={$type}&progressUid={$progressUid}" // unique ID I'm using to track progress from database
}).done(function(data) {
$("#progressbar-box").hide();
clearInterval(progressInterval);
});
progressInterval = setInterval(function() {
$.ajax({
type: "POST",
url: "{$BASE_URL}/ajax/progressShow",
data: "statusId={$progressUid}" // the same uinque ID
}).done(function(data) {
data = jQuery.parseJSON(data);
$("#progressbar").progressbar({ value: parseInt(data.progress) });
if (data.title) { $("#progressbar-title").text(data.title); }
});
}, 500);
});
the progress is correctly updating in database
the JS timer is trying to get the progress, I can see it in console, but all these request are loading the whole duration of the first script, as soon as the script ends, these ajax progress calls are loaded
So, why is the second AJAX call waiting for the first one to finish?
Sounds like a session blocking issue
By default PHP writes its session data to a file. When you initiate a session with session_start() it opens the file for writing and locks it to prevent concurrent edits. That means that for each request going through a PHP script using a session has to wait for the first session to be done with the file.
The way to fix this is to change PHP sessions to not use files or to close your session write like so:
<?php
session_start(); // starting the session
$_SESSION['foo'] = 'bar'; // Write data to the session if you want to
session_write_close(); // close the session file and release the lock
echo $_SESSION['foo']; // You can still read from the session.
After a bit of hair-pulling, I found one other way that these non-parallel AJAX requests can happen, totally independent of PHP session-handling... So I'm posting it here just for anyone getting here through Google with the same problem.
XDebug can cause this, and I wouldn't be surprised if Zend Debugger could too.
In my case, I had:
XDebug installed on my local LAMP stack
xdebug.remote_autostart enabled
My IDE accepting inbound debugger-connections, even though no breakpoints were active
This caused all my AJAX tests to run sequentially, no matter what. In retrospect it makes a lot of sense (from the standpoint of debugging things) to force sequential processing, but I simply hadn't noticed that my IDE was still interacting behind-the-scenes.
After telling the IDE to stop listening entirely, parallel runs resumed and I was able to reproduce the race-condition I had been looking for.
Be aware, that session_write_close()(answer of chrislondon) may not resolve the problem if you have enabled output buffering (default in PHP 7+). You have to set output_buffering = Off in php.ini, otherwise session won't be closed correctly.
When working with APIs, you sometimes need to issue multiple AJAX requests to different endpoints. Instead of waiting for one request to complete before issuing the next, you can speed things up with jQuery by requesting the data in parallel, by using jQuery's $.when() function:
Run multiple AJAX requests in parallel
a.php generates a main HTML page that contains two simultaneous AJAX calls to b.php and c.php. In order for b.php and c.php to share session variables, the session variables must exist BEFORE the first AJAX call. Provided this is true, a.php and b.php can change the value of the session variables and see each other's values. Therefore, create the session variables with a.php while generating the HTML page. At least that's how it works with Rogers shared web hosting.
You could also set
async: true,

Is it possible to 'echo' a sequence of responses from an ajax call

I'm learning and experimenting with jquery/ajax as I develop a website. I have a page that updates a database. I would like a 'sequence' of responses to display on the screen when the user submits their data (I've seen this done on many other sites).
For instance... user submits form and the page displays:
Received Input
Checking Database - recond number xy
Updating Database
Retrieving Information
etc etc
This is just an example but you get the idea.
I have an ajax call that is initiated on 'click' of the submit button (getFormData just serialises all the form data for me and works fine):
var toSend = getFormData($upgrade_db_form);
var formMessageBox = $("#displayResults");
$.ajax({
url: ajaxurl,
data: {
action: "database_action",
formData : toSend
},
type: 'POST',
dataType: 'TEXT',
beforeSend: function() {
//$form.fadeOut('slow');
formMessageBox.html("starting it up");
},
success: function (data) {
formMessageBox.empty();
formMessageBox.html(data);
error: function (xhr) {
// formMessageBox.html("Oops error!");
}
});
I have a function which gets called by ajax:
function upgrade_database_function() {
echo "testing ";
for($i = 0; $i < 99; $i++) {
echo "percent complete ".$i."%";
}
echo "done ";
die(); // this is required to return a proper result
}
I'm using Wordpress and all the ajax side of things works fine, it passes the form data correctly etc, it's just that I get one long output as though it's cache'ing all the echo's up instead of outputting them in sequence.
I've gone through the jquery ajax documentation and couldn't find how to make it behave the way I want it to. I can live with it the way it is but I think it would look a lot better if I could get it working the way I would like.
Can this be done this way or do I need lots of sequential ajax calls to make it work?
I don't know PHP, but i'm guessing that the echo is just writing to the response buffer... so when all the echos are done the whole response will be returned and you would get the effect that you are seeing... You would need to go with a polling system or something along those lines to get the latest status' from the server and display them I would think... Maybe there is some system in PHP that allows this, but as I said, I don't know PHP.
An Example of Long Polling can be found in this article.
http://www.abrandao.com/2013/05/11/php-http-long-poll-server-push/
WARNING: You may have to do some manual managing of locking of the session in PHP so that your long running call doesn't lock your polling ajax calls: See here:
http://konrness.com/php5/how-to-prevent-blocking-php-requests/
Note that you would likely be wanting to:
create one ajax call that starts the execution of some coded that will take a while... you could put messages that have been generated into a session variable for example in a list of some sort. You would need to lock/unlock the session as mentioned to prevent suspension of AJAX polling calls.
you would create a polling method like in the article that might check the session every 500ms or something to see whether there are any more messages, lock the session, remove those messages and return those messages to the client side and display them.
WARNING: Again, I'm not a PHP person, I may have done this once in my life in PHP (can't remember exactly) but I may be wrong and this may not work, from what I've seen though it looks like it is achievable. Hope this gets you on your way!

Execute php from javascript

I'm having some trouble getting some php code working in my app.
The setup is rather easy: 1 button, 1 function and 1 php file.
script.js
$(document).ready(function ()
{
$("#btnTestConnectie").click(testConnectie);
});
function testConnectie()
{
$.get("script/SQL/testConnection.php");
}
testConnection.php
<?php
echo "It works!";
php?>
According to this post, it should work (How do I run PHP code when a user clicks on a link?)
Some sources claim that it is impossible to execute php via javascript, so I don't know what to believe.
If I'm wrong, can somebody point me to a method that does work (to connect from a javascript/jQuery script to a mySQL database)?
Thanks!
$.get('script/SQL/testConnection.php', function(data) {
alert(data)
});
You need to process Ajax result
You need to do something with the response that your php script is echoing out.
$.get("script/SQL/testConnection.php", function(data){
alert(data);
});
If you are using chrome of firefox you can bring up the console, enable xhr request logging and view the raw headers and responses.
Javascript is run by the browser (client) and php is run on the remote server so you cannot just run php code from js. However, you can call server to run it for you and give the result back without reloading of the page. Such approach is called AJAX - read about it for a while.
I see you are using jQuery - it has pretty nice API for such calls. It is documented: here
In your case the js should be rather like:
$(document).ready(function ()
{
$("#btnTestConnectie").click($.ajax({
url: '/testConnection.php',
success: function(data) {
//do something
}
}));
});
[EDIT]
Let's say you have simple script on the server that serves data from database based on id given in GET (like www.example.com/userInfo.php?id=1). In the easiest approach server will run userInfo.php script and pass superglobal array $_GET with key id ($_GET['id']=1 to be exact). In a normal call you would prepare some query, render some html and echo it so that the browser could display a new page.
In AJAX call it's pretty much the same: server gets some call, runs a script and return it's result. All the difference is that the browser does not reload page but pass this response to the javascript function and let you do whatever you want with it. Usually you'll probably send only a data encoded (I prefer JSON) and render some proper html on the client side.
You may have a look on the load() of jQuery http://api.jquery.com/load/
You should place all of your functions in the document ready handler:
$(document).ready(function(){
function testConnectie() {
$.get("script/SQL/testConnection.php");
}
$("#btnTestConnectie").click(function(e) {
e.preventDefault();
testConnectie();
});
});
You will have to have your browser's console open to see the result as a response from the server. Please make sure that you change the closing PHP bracket to ?> in testConnection.php.
One other note, if you're testing AJAX functions you must test them on a webserver. Otherwise you may not get any result or the results may not be what you expect.

jquery, ajax returning weird data?

i've been doing a lot of ajax scripts and every time something seems to be different.
in this case i have a form that i want to post
<form id="sss">
<input id="qqq"/>
<input type="submit" id="s" href="Search!"/>
</form>
<div id="rrr"></div>
and
$('#s').click(function(){
$.ajax({
url: 'foo.php',
data: {
query: $('#q').val()
},
success: function(data) {
$('#rrr').html(data);
}
});
return false;
});
and
if(isset($_REQUEST['query'])){
print_r($_REQUEST['query']);
}
what happens is that in <div id="rrr"></div> gets loaded the print_r($_REQUEST['query']); and all the rest of the html page.
i only want to return $_REQUEST['query']
weird!?
any ideas? What this success: function(data){} actually means?
Thanks
If you are requesting the same page that you are current displaying, then your if statement doesn't stop processing, so the rest of the page is returned as well. You either need to die() afterward, or (recommended) create a separate page entirely dedicated to handling AJAX requests. Here's an example of how to properly stop processing:
if (isset($_REQUEST['query'])) {
print_r($_REQUEST['query']);
die(); // stop processing.
}
In regards to your second point, I think you might be misunderstanding the technical details of what's actually happening here:
Client requests foo.php from server. Server executes foo.php according to the logic in the page, and sends response output to browser. Browser renders the page.
Client sends AJAX request (which is nothing more than a request that happens asynchronously, i.e., separately from the browser loading a page) to foo.php?query=...
Server executes foo.php?query=... (just like it did in step (1)!), which causes the first if to trigger before returning the rest of the html in response, so the same page is returned except with the query output at the top (Try going directly to foo.php?query=... in your browser and I think you'll see what I mean).
However, instead of the response being rendered in the browser, since it was an AJAX request, the response is captured into a variable, data.
The callback function success(data) is executed, passing the exact output returned from the server as-is from the AJAX request (i.e., the variable contains the same as viewing the source of foo.php?query=... in your browser), which is then processed according to your logic. In this case, you are dumping the contents into a div, so you see the output correctly.
Please take a moment to install and run Fiddler, so you can see the exact data that is flowing back and forth as you load the page in your browser, and then watch what happens as you make an AJAX call. Perhaps it will make the data flow and results you are getting much clearer.
Hope this helps!

JSONP Request In jQuery 1.4.2. Does Not Even Query Remote URL?

I have here a test page that should do a jQuery JSONP cross-domain request not once, but twice:
http://www.starcitygames.com/json_test.php
And it should query this here page here to pull up some test data:
http://scg.im/ajax/fetch_recent_URLs.php?callback=fred
After bashing my head against the wall for an entire morning where I got absolutely zero response from this script, pro or con, I put a mail() call in the fetch_recent_URLs script to mail me whenever the remote page was loaded.
It turns out that despite several loadings, tweakings, etc. of the script, it never actually calls the scg.im page. The script isn't broken, returns no fatal errors in JavaScript, et cetera - it just doesn't actually ever seem to fire the AJAX call.
Even more perplexingly, regular JSON calls (to this domain) work fine.
The script(s) are as such:
$.ajax({
url: "http://scg.im/ajax/fetch_recent_URLs.php",
type: "GET",
dataType: "jsonp",
error: function(xhr, status, error) {
alert("error");
},
success: function(json) {
alert("success");
}
});
$.getJSON("http://scg.im/ajax/fetch_recent_URLs.php?callback=?", function(rtndata) {
alert("Returned!");
});
Both are taken from various test pages that claims this works. I've also tried it in jQuery 1.6, changed the header, etc., all encountering the same problem; no matter what I do, jQuery never actually calls the page. (Again, I know this because the script mails me every time it's loaded, and it doesn't email me at all when I load this page.)
Any idea why this is not working? I'm doing, as far as I can tell, everything according to plan (and about five variations on these scripts to boot).
Edit: SOLVED! I figured it out, and it's entirely stupid.
If you have NoScript enabled for FireFox (and you arguably should), AND you have not allowed scripts from the new domain (in this case, scg.im), then NoScript will prevent the domain request before it even begins. Good security. Thoroughly baffling.

Categories