Delay PHP execution until JavaScript cookie set? - php

I am trying to delay PHP execution until a cookie is set through JavaScript. The code is below, I trimmed the createCookie JavaScript function for simplicity (I've tested the function itself and it works).
<?php
if(!isset($_COOKIE["test"])) {
?>
<script type="text/javascript">
$(function() {
// createCookie script
createCookie("test", 1, 3600);
});
</script>
<?php
// Reload the page to ensure cookie was set
if(!isset($_COOKIE["test"])) {
header("Location: http://localhost/");
}
}
?>
At first I had no idea why this didn't work, however after using microtime() I figured out that the PHP after the <script> was executing before the jQuery ready function. I reduced my code significantly to show a simple version that is answerable, I am well aware that I am able to use setcookie() in PHP, the requirements for the cookie are client-side.
I understand mixing PHP and JavaScript is incorrect, but any help on how to make this work (is there a PHP delay? - I tried sleep(), didn't work and didn't think it would work, since the scripts would be delayed as well) would be greatly appreciated.

It is not impossible to do what you are trying to do, as other answers have stated, but it is also not trivial and seriously a bad idea for your server to wait per-request for the client to "set a cookie."
But it can be done.
PHP code would write a <script> block for setting the cookie.
PHP code would begin an idle loop, monitoring a session variable. Not a cookie. The cookies for the PHP script executing are already set and are not going to change by JavaScript.
JavaScript block written in #1 would also need to make an AJAX call to the server. The PHP script it calls should set the cookie you care about, but also set the session variable #2 cares about.
The original script, monitoring the session, should wake up and continue as you planned.
While PHP does execute before JavaScript, all browsers incrementally load the HTML/CSS/JavaScript content generated by PHP (or any server-side language). Because of the incremental loading, it is possible for your PHP script to delay for JavaScript to do something (as outlined above) before continuing. But your server is going to have a lot of headache to deal with, such as how long to wait for JavaScript to break the idle loop in #2 if the JavaScript request never comes through, etc.
This is not a normal execution flow for a standard webpage. Unless you really need this, perhaps consider this a proof-of-concept answer.

PHP executes first in its entirety on the server. It then sends the final HTML/Javascript/CSS output to the browser. The browser receives this and executes any Javascript.
It is fundamentally impossible to do what you're trying to do with that code. PHP and Javascript run at completely different times in completely different environments. You need to start another request to the server once Javascript set the cookie to start another PHP script. Redirect using Javascript or look into AJAX.

If you want to execute JavaScript before PHP, you'll have to divide it into two requests. You can load your JavaScript in one request, and execute an Ajax request after your cookie is set. Keep in mind that all server-side code is processed before the client-side code will be executed.
I have to ask though.. why do you want to do it this way? What are you trying to accomplish?

Cookies can be set in PHP with setcookie
setcookie("test",1,time()+3600);

This can't be done within a single request. PHP runs first, then JavaScript. Even incremental loading won't help, because cookies are sent via headers and those have already been sent by the time PHP runs.
However, you can let the JavaScript set the cookie and then reload the page once it's done by using location.reload(). PHP would then only need to print the JavaScript, like so:
<?php
if(!isset($_COOKIE["test"])) {
?>
<script type="text/javascript">
$(function() {
// createCookie script
createCookie("test", 1, 3600);
// reload the page, which would send the cookie at the next request
location.reload();
});
</script>
<?php
// stop execution and wait for JavaScript to call you again.
exit;
}
?>

The PHP executes on the server-side, the JS on the client-side. In a single GET request from the browser, the PHP will always execute before the JS.

Related

this.checked creating false positive?

I have a page that has 4 checkboxes that are checked by default. If you uncheck a box, it writes a cookie so that return trips to the page will have saved preferences. The problem I'm having is that the cookies seem to be written no matter what. Going to the page for the first time should create no cookies, but unchecking a box should throw the following code. As it stands, the first time I'm going to my site, the cookies are created.
Where have I gone wrong (I wouldn't be surprised if it is in multiple places).
$('#mycheckbox').change(function() {
if (! this.checked) {
<?php setcookie('key', 'Value', time() + 4800); ?>
}
});
No, this.checked works.
The problem is that the PHP code will always be run, since it's run on the server-side and not interpreted by the browser. All PHP code is executed before the browser even gets the files.
A solution would be to put that PHP in an external file and use jQuery $.ajax to request that file, which would run the code only when desired.
You could also check out the jQuery $.cookie plugin.
As #MarkB already said you are mixing up javascript and php. In this case you should set your cookie with javascript in stead of php. See this post to find out more.
The code as you have it now will always set the cookie, as you already noticed, because the server ignores the javascript code and just runs the php code to set the cookie.

Different page conten when JS is disabled

i've got a slight problem with JS enabled detection.
not too big, because i know i'm on the right track.
but here's my deal:
when i try to set a cookie in JS (jQuery) using this code
$(window).load(function(){
$.cookies.set('c_jsEnabled', 'true');
});
or just in plain JS using this code
function setCookie()
{
document.cookie='c_jsEnabled=true';
}
<body onload="setCookie();">
and then try to detect it in PHP using this code
if($_COOKIE['c_jsEnabled'] == 'true')
{
if(file_exists('./main.php'))
{
require_once ('./main.php');
}
echo getIndex();
}
else
{
if(file_exists('./noJS.php'))
{
require_once ('./noJS.php');
}
echo getIndex();
}
setcookie('c_jsEnabled', '');
it takes 2 page refreshes to actually get the right value into PHP.
my guess is that this bascially means that the PHP script is executed before the JS function is fired.
could this be because all codes shown above are in the same script (index.php)?
This is kind of a problem for me, because i want to prevent people from using my website when they have JS disabled.
is there a way to set the cookie before php tries to get the cookie variable?
PHP is always "fired" before JavaScript because PHP is processed on the server and then sends out the HTML and JavaScript for the browser to process and render. You can never expect JavaScript to execute before PHP for this reason.
In your case, use JavaScript to set the cookie and then do a redirect to refresh the page so PHP can get the cookie value and act accordingly.
You should be setting the cookie directly from the PHP file. That way, you know that it exists, and more importantly, you have control of the cookie. You can set it from the client, but that will always execute after the HTML has been sent to the browser, so the PHP file won't get it until the next request.
PHP only sends the cookie header when content is sent to the browser. Javascript then executes after that, so you would need a second load of the page to detect the cookie.
This can trigger infinite redirection loops (especially if the user has cookies disabled), so be careful.
To disable the site to users without Javascript, consider the following.
<div id="noscript" style="width:100%; height:100%; z-index:999; position:absoloute; top:0px; left:0px; background-color:#CC9900; display:block">
Please Enable Javascript!</div>
<script type="text/javascript">
document.getElementById('noscript').style.display = 'none';
</script>
I find the <noscript> tag is unreliable (there was a bug in iOS causing it to only show when there was Javascript, if I remember correctly).
A second option:
You can have the PHP check for a cookie. If it isn't set, have it redirect (header("Location: aaa.html");) to a page with the Javascript to set the cookie and redirect back. (Alternatively, have the PHP output Javascript to set the cookie reload the page.) You then only have to worry about users who "spoof" the cookie, although you will also lock out users who have cookies disabled.
Nope - PHP will always be called before client-side JavaScript, so with this method you'll always have to refresh the page at least once. You're better to develop your site so that non-JS users have a worse-but-still-acceptable experience, or at worst use the <noscript> HTML tag to serve alternative content to those users.
You can't get a cookie in PHP that's being set by JavaScript before the page renders/executes.
You could set the cookie using PHP, however. That will ensure it's set and available regardless of JavaScript or multiple page refreshes.

getting cookie from an external javascript in php before generating HTML output

Is it possible getting cookie from an external js with Php before generating HTML to the browser?
Something like
<?
//Get if i have some cookie information
if($_COOKIE["js_app"])
$cookie_js = $_COOKIE["js_app"];
//now, talk with some app.js
if($cookie_js)
$cookie = some_function(target = 'some_domanin/app.js',$cookie_js);
else
$cookie = some_function(target = 'some_domanin/app.js');
$_COOKIE["js_app"] = $cookie;
//now i can generate the HTML output.
....
?>
It isn't possible because the javascript would never be executed. Your some_function (assuming it used cURL to make the request and pass along the cookie), would just receive the javascript code (like what happens when you view javascript source in your browser).
When JS is loaded by the browser, the browser's javascript interpreter handles parsing and executing the javascript.
Edit: Hmm... googling for "php javascript interpreter" resulted in http://j4p5.sourceforge.net/index.php. Never used it before and probably never will but if you don't need to interact with the user-side of things, that might help you out.
You are looking for a way to send request with cookies, and get the cookies from the response using PHP, right? I think PEAR HTTP_Request is what you are looking for, although you have to install it on your server as a package.
If that is not an option, I guess you will have to do HTTP requests using sockets.
UPDATE: If you are setting the cookies using Javascript, you will have to parse the javascript - not really an option. These functions only work when the cookies are set server-side.

Disable php script via Javascript

I have a situation like this.
<php>
<redirect the page >
<exit>
<javascript>
<redirect the page again>
I want to have javascript that basicall disables the PHP redirect. So if Javascript is enabled on the browser, the javascript redirect will work, if it disable, the PHP redirect will work. Should I just enclose the PHP code in span and make it invisible? Any ideas?
Addition ok this is not a simple redirect. the form authentication is rather odd. Register.php -> register_submit.php -> Was there an error -> yes go back to register.php (everything is javascript at this point). What I have added is PHP authentication as well so if I see javascript is not enabled, I take the user to register.php *after it does the regular checking of fields *.
PHP is a server-side technology. By the time Javascript even sees what's happened, it's too late.
Short answer, JS can't intercept/block PHP (as long as PHP is being called first).
Order of events:
Client requests page
PHP executes and generates output of page
Browser receives output
Browser begins parsing what was sent by what PHP already spit out.
Remove your PHP redirection and add this in your <head>:
<noscript>
<meta http-equiv="refresh" content="0; http://www.example.com/1" />
</noscript>
<script>
window.location = 'http://www.example.com/2';
</script>
This will redirect to http://www.example.com/1 when javascript is disabled, and to http://www.example.com/2 when it's enabled.
PHP code is executed on the server-side, while JS is client-side. So with that structure the PHP will kick in before the JS is executed. If you want JS to control PHP you need to make use of AJAX to control it.
Also enclosing PHP code in a "span" won't have any effect.
Javascript and PHP do not directly interact (exceptions apply, don't worry about them now :D). The best way to implement this type of interaction between these two disparate languages is to use the query string or cookies.
I think there may be some confusion here about when and how PHP is executed as opposed to when and how javascript is executed. Think of PHP as the factory - the goods are physically produced there. Think of your server as the loading dock, the internet as the shipping company. Your browser is the store, HTML is the shelves; Javascript is the window decorations on the store that sells the merchandise. The window decorations have no affect on the production, the factory can make some window decorations, but it doesn't use them, it just ships them right along with the merchandise for the store to use. PHP is the factory, javascript is the decoration. There are some problems with taking this analogy too literally, but there it is in a nutshell.
You can make the PHP redirect conditional on the presence or absence of a specific query string variable:
<?php
// redirect if $_GET['no_redirect'] is NOT set. Reverse the true/false to invert this rule
$do_redirect = (isset($_GET['no_redirect']) === false ? true : false);
// perform the redirect, if required
if ($do_redirect === false)
header('Location:http://mydomain.com');
?>
Javascript:
window.location = 'http://mydomain.com/?no_redirect=1';
EDIT If you're trying to detect if javascript is enabled, then the best way is for javascript to set a cookie if it is enabled. PHP can then check for this cookie, and if it isn't found then you'll know that javascript didn't get a chance to set it, so it must be disabled (or the user edited their cookies).
Take a look at some code snippets for dealing with cookies in javascript, and check out the documentation for dealing with cookies in PHP.

PHP usleep/sleep inside output buffer

I have a PHP application containing these files: landing.php, redirect.php, ajax.php
on a page call to landing.php, I execute a javascript code to capture certain data, and issue an AJAX POST to ajax.php which inserts them into DB. Finally php header() redirects to redirect.php
Currently the above feature is using output buffering, but the header() is executed too soon that the AJAX POST is not finished..ie, no DB query is made.
I tried using sleep() usleep() before header() but they are not working. As I am not very familiar with output buffering, would you please offer a kind hand?
Thank you.
<?php ob_start(); ?>
<scripts type="text/javascript">
var data = 'blah..blah..blah..';
ajaxPost('ajax.php', data);
</scripts>
<?php
sleep(2); // <---- I want the script to sleep here and wait for the AJAX to finish
header('c.php)
ob_end_flush();
?>
If I understood you correctly, you have a fundamental misunderstanding on how web applications work.
Your PHP script can't wait for the AJAX bit to execute, because the whole script is first run on the server, and the output -- part of which the AJAX call is -- is then sent to the browser. You have to rethink the way you're doing this.
For instance, you could have the JavaScript first make the AJAX call, and then redirect the browser.
Edit: OK, now that I've thought about this for a while more, I can see how something like this might work when you're not using output buffering, if the browser executes the script as soon as it sees it (without having the full page loaded). If that is indeed the case, then you're still relying on the browser's timing, the quality of the user's internet connection and so on to keep things in sync. That is decidedly not a good thing.
However, the only way that could work is if the AJAX call got outputted to the browser before your header call -- which is not possible! Headers need to be sent before the content in the HTTP response (which is why you're using output buffering in the first place), so either you won't output the JavaScript or the header call will fail. So I recommend you rethink your approach.

Categories