I'm working on a simple Ajax exercise where I separate the query, the Ajax, and the url that Ajax calls. In short, I run a query in one page and attach the resulting array to $_SESSION, then I display some html and the Ajax code calls a third page to get the elements from the array one by one via a counter attached to the $_GET superglobal. The three files are linked by require_once().
When the page loads initially, all is as expected. The $_SESSION contains the entire array pulled from MySQL, and the $_GET is null.
Once I click on the button to execute the Ajax code, the $_GET value changes and receives the value of the counter, as expected.
However, $_SESSION ceases to exist. The var_dump now returns null and I get an error Notice: Undefined variable: _SESSION in C:\wamp\www\.....\ajax.php. I don't understand why that is.
Here is my code. First, index.php :
<?php
session_start();
$dbhost = "localhost";
$dbuser = "admin";
$dbpass = "XXXXXXX";
$dbname = "test";
mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($dbname) or die(mysql_error());
$query = "SELECT ae_name FROM ajax_example";
$qry_result = mysql_query($query) or die(mysql_error());
$result;
while($row = mysql_fetch_array($qry_result,MYSQL_ASSOC)){
$result[]=$row;
}
$_SESSION['array']=$result;
require_once ("viewUsers.php");
require_once ("ajax.php");
?>
Then the html and ajax code in viewUsers.php:
<html>
<body>
<script type="text/javascript">
<!--
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (tryMS) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (otherMS) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = null;
}
}
}
return request;
}
var indx=0;
function calcIndex(){
return indx++;
}
function ajax(){
ajaxRequest = createRequest();
var index=calcIndex();
var url="ajax.php?index=" + index;
ajaxRequest.open("GET",url, true);
ajaxRequest.onreadystatechange = display;
ajaxRequest.send(null);
}
function display(){
if(ajaxRequest.readyState == 4){
var ajaxDisplay = document.getElementById('ajaxDiv');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
//-->
</script>
<form name='myForm'>
<input type='button' onclick='ajax()' value='Show next name' />
</form>
<div id='ajaxDiv'>Your result will be displayed here</div>
</body>
</html>
And then the PHP that receives the array from $_SESSION and (should) return the next item based on the value of $_GET['index']. The file is ajax.php.
<?php
var_dump('Get value in ajax.php',$_GET); // The values are as expected
var_dump('Session value in ajax.php',$_SESSION); // This global cease to exist after I click the button
if(isset($_SESSION['array'])){
$array=$_SESSION['array'];
$cnt=count($array);
$index=null;
if(isset($_GET['index'])){
$index=$_GET['index'];
if($index>=$cnt){
$str="And that's it....";
}else{
$str="The next name is ".$array[$index]['ae_name'];
}
echo $str;
}
}
?>
The problem is that session in ajax.php is not started / resumed.
When you call index.php, it is:
index.php -> .. -> ajax.php (SESSION EXISTS (session_start() called in index.php))
then you request your ajax.php through ajax:
html -> ajax.php (SESSION DOESNT EXISTS (session_start() was not ever called as we dont come from index.php))
You just need to initialize / resume session in your ajax.php, but you have to check if its not already initialized from index.php. Put this chunk of code into your ajax.php file:
if(!session_id()) // check if we have session_start() called
session_start(); // if not, call it
ajax.php needs a session_start() at the beginning, otherwise, when you call it standalone via ajax, you won't have a session, hence no $_SESSION var.
From PHP DOC
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
When session_start() is called or when a session auto starts, PHP will call the open and read session save handlers. These will either be a built-in save handler provided by default or by PHP extensions (such as SQLite or Memcached); or can be custom handler as defined by session_set_save_handler(). The read callback will retrieve any existing session data (stored in a special serialized format) and will be unserialized and used to automatically populate the $_SESSION superglobal when the read callback returns the saved session data back to PHP session handling.
Without calling session_start definitely $_SESSION would not be populated accordingly why advice is to always call session_start if you in your script if you are going to be using sessions .
Quick Few steps
Remove require_once ("ajax.php"); from index.php its not needed there
PHP CODE
$_SESSION['array']=$result;
require_once ("viewUsers.php");
require_once ("ajax.php"); //<------ remove this
Add session_start(); to ajax.php
From PHP DOC on mysql_query
Use of this extension is discouraged. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:mysqli_query()
PDO::query()
Your index.php should finally look like this
session_start();
// Put this in config file
$dbhost = "localhost";
$dbuser = "admin";
$dbpass = "XXXXXXX";
$dbname = "test";
$array = array();
//Start DB Connection
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
$query = "SELECT ae_name FROM ajax_example";
$result = $mysqli->query($query);
//Get Information
while ( $row = $result->fetch_assoc() ) {
$array[] = $row;
}
$result->free();
$mysqli->close();
// Add Info to session
$_SESSION['array'] = $array;
require_once ("viewUsers.php");
#JDelage,
Your question has a very simple solution - Just add session_start() at the top of the ajax.php file.
However, the major problem here is lack of organization in your code structure.
Session / Configurations are preloaded in most of the actions. And these are included in a file which is loaded in every call.
Your file ajax.php apparently seems to be an independent file, however is dependent upon index.php, meanwhile index.php depends on ajax.php (require_once).
So the best work around for your type of code is as follows.
bootstrap.php
<?php
// just to check to prevent overwriting of your configs / preloads.
if(!defined("INITIALIZED")){
session_start();
//.. some other basic settings if you require
define("INITIALIZED", 1);
}
?>
index.php
<?php
include_once "bootstrap.php";
// .. your code
require_once("viewUsers.php");
require_once("ajax.php");
ajax.php (Yes you need session_start() here, because when you make asynchronous request to this file, it acts as an independent request regardless of index.php. AJAX call is a client side asynchronous request, not a server side. )
<?php
include_once 'bootstrap.php';
// .. your code
viewUsers.php
// since your viewUsers.php file isn't an independent file and is included by index.php only, you can simply add this line at the top to prevent direct invocation of the file.
<?php
if(!defined("INITIALIZED")){die();}
PS:
There isn't an unique solution. An approach is what you have to decide. Your approach is an approach, which isn't any kind of approach. Rest is fine.
I hope I have answered your queries.
Regards,
You have a number of if conditions that are making it difficult for you to see errors. Add some echo statements at those locations to see what is happening in your program flow. It will be easier to troubleshoot. For example:
<?php
//session_start();
echo 'You sent ' . $_GET['index'] . '<br>'; //Ensure index value arriving
if(isset($_SESSION['array'])){
$array=$_SESSION['array'];
$cnt=count($array);
$index=null;
if(isset($_GET['index'])){
$index=$_GET['index'];
echo 'Got to here<br>'; //Another checkpoint - send something back
if($index>=$cnt){
$str="And that's it....";
}else{
$str="The next name is ".$array[$index]['ae_name'];
}
echo $str;
}else{
echo 'GET var "index" was not set<br>';
}
}else{
echo 'SESSION var "array" was not set<br>';
}
?>
Of course, you will remove those echo statements as you fix your code... They are only temporary, for debugging.
I faced similar issue. I found that in one of the ajax call I forgot to call session_start().
when I ensured that I session_start() is always called in all the php code that are called thru ajax, then this problem went away.
When using AJAX sometimes the session is not carried over. In your AJAX post/get include the sessionID. Then on the receiving end do something like:
$sid = ($_POST['sid']) ? $_POST['sid'] : ''; //Check for posted session ID
session_start($sid); //Start session using posted ID or start new session
*Old-school method, yes, but tried and true.
Related
I've got this session variable, which was initiated in index.php
<?php
$sid = session_id();
if (empty($sid) {
session_start();
}
//value of the variable can be changed and saved before coming back to the index
if(!isset($_SESSION['context'])){
$_SESSION['context'] = 1;
}
//...
?>
Later a script is used to create or update a database entry.
entryupdate.php:
<?php
include_once("template.php");
/*....*/
$sid = session_id();
if (empty($sid)) {
session_start();
}
/*....*/
//Create a new entry, context is not given in the $input_object at this point.
$template = new Template($input_object);
$context = $template->getContext();
?>
template.php is a script where only the Template Object is defined, so I don't call $session_start in it, my rationale being that it would always be called by the scripts including it, as it is in the case I'm describing here. Here is the relevant code:
<?php
class Template
{
private $m_context;
//other private parameters
function __construct($arguments_object){
if(!is_null($arguments_object)){
/*....*/
$this->m_context = $arguments_object->context;
/*....*/
}
}
/*....*/
function getContext(){
if(!empty($this->m_context)){
return $this->m_context;
}else{
//this would be our case, as the parameter was not initialized yet.
return $_SESSION['context'];
}
}
/*....*/
}
?>
Now, a colleague stumbled on an error and upon investigation, I found out that the $context was set to NULL. When I tried to reproduce the issue, the context was correctly initialized. And to be honest, for the few years the tool has been used, it is the first time this kind of issue was encountered.
I've also checked, at no point I am unsetting this particular session variable.
Am I making a false assumption there, in thinking that template.php would find the session variable when the session was started in entryupdate.php where it was included and used?
I am using a jquery function to call a getdata.php file like this -
$("#tasks").load("getdata.php?choice=" + $("#projects").val());
The getdata.php echoes back results dynamically to the callee.
<?php //getdata.php
global $user_id; //<--These variables are defined in the callee file
global $con;
$choice=$_GET['choice'];
$query="SELECT task_id,title from tasks where user_id=$user_id AND proj_id=$choice";
$result=mysqli_query($con,$query) or die(mysqli_error($con));
if((mysqli_num_rows($res))!=0)
{
while (list($task_id, $title) = mysqli_fetch_row($result))
{
echo "<option value=$task_id>$title</option>";
}
}
else
{
echo "<option>No current Tasks</option>";
} ?>
Is there any way by which I can access the variables in the callee file from here. I tried using global as would normally be the case with included files but that's not working here.
You may consider using $_SESSION variables to set variables that are available to both your callee file and getdata.php.
Why not put them in the request ? `Something like
$("#tasks").load("getdata.php?choice=" + $("#projects").val() + "&user_id=" + user_id;
(How to pass PHP variables to js as already got a lot of answers on SO)
then in getdata.php
$user_id = $_GET['user_id'];
for the DB connection, you can create a kind of config file that you include on every script
config.php
function getDBConnection() {
blah...blah ...
return $con;
}
in getdata.php as in every script that need it :
require_once yourpath/config.php;
$con = getDBConnection();
For security reasons, if your config file contains passwords, login , etc ... put it outside
your web directory.
I am new to PHP and even newer to SESSIONS
I am working with the Instagram API and I am successfully able to authorize an app, and redirect to a page to display content.
My main folder is called Monkey and it has a sub folder called Instagram.
MY callback url for instagram is success.php located in the instagram folder. When I successfully retrieve an access token from Instagram it redirects to the index file in the Monkey folder.
On my success page, I am creating an array full of data called instaArray. I am trying to pass the array from the success.php in the instagram folder, to the index.php in the monkey folder.
My redirect is simply
header( 'Location: ../index.php' );
Because I am new with sessions, I guess I am doing something wrong. I figured it was straight forward, but I suppose not ha.
On the success.php page, after I build the array I have this
session_start();
$_SESSION['instagram'] = $instaArray;
I thought that should create a session that holds my array InstaArray.
Then, on the index.php page in Monkey, I have this
<?php
session_start();
$get_instagram = $_SESSION['instagram'];
print_r($get_instagram);
?>
But absolutely nothing happens. I've even tried to set the session instagram to a simple numerical value or 1, $_SESSION['instagram'] = 1; and get that on the index page, and it doesn't work either.
Am I doing something horribly, terribly wrong? I've read up on sessions, but because it's new, it's still a little confusing.
Thanks for the help, and I hope I was able to explain everything properly.
EDIT: Here is my success.php page in full
<?php
require 'src/db.php';
require 'src/instagram.class.php';
require 'src/instagram.config.php';
// Receive OAuth code parameter
$code = $_GET['code'];
// Check whether the user has granted access
if (true === isset($code)) {
// Receive OAuth token object
$data = $instagram->getOAuthToken($code);
// Take a look at the API response
$username = $data->user->username;
$fullname = $data->user->full_name;
$id = $data->user->id;
$token = $data->access_token;
$user_id = mysql_query("select instagram_id from users where instagram_id='$id'");
if(mysql_num_rows($user_id) == 0) {
mysql_query("insert into users(instagram_username,instagram_name,instagram_id,instagram_access_token) values('$username','$fullname','$id','$token')");
}
//Set Cookie
$Month = 2592000 + time();
setcookie(instagram, $id, $Month);
// Set user access token
$instagram->setAccessToken($token);
// Retrive Data
$instaData = $instagram->getUserFeed();
// Create Instagram Array
$instaArray = array();
$count = 0;
// For each Instagram Post
foreach ($instaData->data as $post) {
$instaArray[$count]['post_id'] = $post->id;
$instaArray[$count]['name'] = $post->user->username;
$instaArray[$count]['profile_img'] = $post->user->profile-picture;
$instaArray[$count]['img_url'] = $post->images->standard_resolution->url;
$instaArray[$count]['caption'] = $post->caption->text;
$instaArray[$count]['like_count'] = $post->likes->count;
$instaArray[$count]['comment_count'] = $post->comments->count;
$instaArray[$count]['created_time'] = $post->created_time; //Unix Format
$count++;
}
// Start Session For Array
session_start();
$_SESSION['instagram'] = serialize($instaArray);
header( 'Location: ../index.php' ) ;
} else {
// Check whether an error occurred
if (true === isset($_GET['error'])) {
echo 'An error occurred: '.$_GET['error_description'];
}
}
?>
Why not use an ID and then cookies rather than sessions + data (which are usually store on the server in text files in a temporary directory)? And keep all data within a database than allow the client to be accessible to the data. Sessions are also temporary.
Note, do you know if you have "globals" on?!
"Please note when working with sessions that a record of a session is not created until a variable has been registered using the session_register() function or by adding a new key to the $_SESSION superglobal array. This holds true regardless of if a session has been started using the session_start() function."
Reference:
http://www.php.net/manual/en/function.session-register.php
make session_start() first line after php
<?php
session_start();
and remove it from anywhere ele on page.
session_start() should be your first line in index.php also as in success.php
Note: The session_start() function must appear BEFORE the tag:
REF : http://www.w3schools.com/php/php_sessions.asp
I think you need to unserialize() your array in index.php.
$get_instagram = unserialize($_SESSION['instagram']);
How would I create a cookie that would store the randomly added body class for one browser session or for one day. My intention would be to randomly give every user a body background image and then store that image so that it won't change every pagereload or when they go to page 2.
Site http://www.midnightlisteners.com/
i am using this jQuery plugIn: https://github.com/carhartl/jquery-cookie
but it does not work somehow
My jQuery code:
the code that I use:
if($.cookie('userBackground') === null) {
var classes = ['body-bg1','body-bg2', 'body-bg3', 'body-bg4'];
var randomnumber = Math.floor(Math.random()*classes.length);
var chosenClass = classes[randomnumber];
$('body').addClass(chosenClass );
$.cookie('userBackground', chosenClass, { expires: 7, path: '/' });
} else {
//todo verify cookie value is valid
$('body').addClass($.cookie('userBackground'));
}
Errors i am getting:
Uncaught ReferenceError: require is not defined
Uncaught TypeError: Object function (a,b){return new e.fn.init(a,b,h)} has no method 'cookie'
Are there other ways to do this? php? pure javascript?
UPDATE:
If you want to make it only last the length of the session then just use the session instead:
<?php
if(!isset($_SESSION['bgclass'])) {
// lets make our cookie!
$classes = array('body-bg1','body-bg2', 'body-bg3', 'body-bg4');
$classIndex = array_rand($classes);
$_SESSION['bgclass'] = $classes[$classIndex];
}
$bgclass = $_SESSION['bgclass'];
?>
This way after the session times out or the browser is closed the user will get a new bgclass value.
If you already have php running i would do it that way. Much better to handle this server side if you can. Its also a bit simpler:
<?php
if(!isset($_COOKIE['bgclass'])) {
// lets make our cookie!
$classes = array('body-bg1','body-bg2', 'body-bg3', 'body-bg4');
$expire = time()+(60*60*24); // expire 1 day form now
$classIndex = array_rand($classes);
$bgclass = $classes[$classIndex]; // had $class here as opposed to $classes
setcookie('bgclass', $bgclass, $expire);
} else {
$bgclass = $_COOKIE['bgclass'];
}
?>
<html>
<head></head>
<body class="<?php echo $bgclass ?>">
...
</body>
</html>
The key thing to remeber is that a cookie is essentially a response header so you have to do this before headers have been sent (ie. anything from php is output to the browser).
I'm trying to implement and authentication system with jQuery and PHP. All the php work is made in the controller and datahandler class. There is no php code inside the .html files, all the values in .html files are rendered via jQuery that request the data from php server. So what I'm trying to do is:
When user clicks the login button, the jQuery makes a call to the authenticate() method in my controller class, it checks if the user is correct and stuff, and if it is, start the session and set the user_id on the session so I can access it later, and returns the userId to the jQuery client again.
After that, if everything is fine, in jQuery I redirect it to the html file. On the html file I call a jQuery from the <script> tag that will handle other permissions. But this jQuery will access the method getPermissionString (from the same class of authenticate() method mentioned before), and it will need to get the session value set in authenticate method.
The Problem:
When I try to get the session value inside getPermissionString() it says:
Notice: Undefined variable: _SESSION
I've tried to check if the session is registered in the second method, but looks like it's not. Here is my PHP code.
Any idea? Thanks.
public function authenticate($login, $password)
{
$result = $this->userDataHandler->authenticateUser($login, $password);
if(is_numeric($result) && $result != 0)
{
session_start();
$_SESSION["uid"] = $result;
if(isset($_SESSION["uid"]))
{
echo "registered";
$userId = $_SESSION["uid"];
}
else
{
echo "not registered";
}
echo $result;
}
else
{
echo 0;
}
}
public function getPermissionString()
{
if(isset($_SESSION["uid"]))
{
echo "registered";
$userId = $_SESSION["uid"];
}
else
{
echo "not registered";
}
}
Before you can access $_SESSION in the second function you need to ensure that the program has called session_start() beforehand. The global variable is only populated when the session has been activated. If you never remember to start a session before using it then you can change the php.ini variable below:
[session]
session.auto_start = 1
Further, you said that you're using a class for your code. In this case you can also autos tart your session each time the class in created by using magic methods:
class auth {
function __construct() {
session_start();
}
function yourfunction() {
...
}
function yoursecondfunction(){
...
}
}
If you don't have session.auto_start enabled, and authenticate and getPermissionString are called on two different requests, you need to call session_start() in each function.
If you need more information on how the session ID is passed, just read Passing the Session ID
You should not use that function if session is not started. So throw an exception:
public function getPermissionString()
{
if (session_status() !== PHP_SESSION_ACTIVE)
{
throw new Exception('No active session found.');
}
if(isset($_SESSION["uid"]))
{
echo "registered";
$userId = $_SESSION["uid"];
}
else
{
echo "not registered";
}
}
This ensures the pre-conditions of your functions are checked inside the function so you don't need to check it each time before calling the function.
You will now see an exception if you wrongly use that function and it will give you a backtrace so you can more easily analyze your code.
For php sessions to work you have to call session_start() every time you script is requested by the browser.