Does Php always create a session file as soon as session_start() is called, even though there's nothing to keep track of (= no variable written in $_SESSION[])? If so, why?
Default PHP file-based sessions encode the session ID into the session file's filename. Since that's the only place the ID is kept normally, SOMETHING has to be kept to store the id. That means you'll get a file created, even if nothing is EVER written to $_SESSION.
In PHP-like pseudo code, basically this is occuring:
function session_start() {
if (isset($_COOKIE[ini_get('session.name')])) {
// session ID was sent from client, get it
$id = $_COOKIE[ini_get('session.name')];
} else {
// no session ID received, generate one
$id = generate_new_id();
setcookie(ini_get('session.name'), $id, ......);
}
$session_file = ini_get('session.save_path') . '/sess_' . $id;
if (file_exists($session_file)) {
// found a session file, load it
$raw_data = file_get_contents($session_file);
$_SESSION = unserialize($raw_data);
} else {
// brand new session, create file and initialize empty session
file_put_contents($session_file, serialize(array());
$_SESSION = array();
}
// lock the session file to prevent parallel overwrites.
flock($session_file);
}
Related
I read this article: http://smallbusiness.chron.com/hiding-url-parameters-php-redirect-33163.html
which explains how to but I'm don't understand how you redirect with the header as they say in there.
For storing in sessions this is code I use
session_start();
function input_val($key, $remember = true) { //use input_val('nameofinputfield')as value to be able to store in session
$value='';
if(isset($_REQUEST[$key])) {
$value = $_REQUEST[$key];
//Store value in session if remember = true
if($remember) {
$_SESSION[$key] = $value;
}
return $value;
} else {
//Return session data
return isset($_SESSION[$key]) ? $_SESSION[$key] : $value;
}
}
Let's say, you want to pass a username and email parameter from your script1.php to script2.php. If you are using POST method, in the URL the parameters won't show, and you can access your passed variables through $_POST global variable. But, if you want to use GET method for any reason, or you want to store data in $_SESSION you can do this.
You can try to use this in your script2.php:
session_start();
if (count($_GET)) {
foreach ($_GET as $key => $value) {
$_SESSION[$key] = $value;
}
header("Location: " . $_SERVER["PHP_SELF"]);
}
//At here, you can access all of your parameters from $_SESSOION variable
var_dump($_SESSION);
I will try to explain it as simple as I can, it's not that difficult.
When a user is in a session with the php he stores a little blob of text in the browser, this text is like a user ID that lasts until he close his browser. The php script can tell and extract information from the server, like parameters, by knowing his ID. This is not a cross-server feature though and it isn't persistent, unlike cookies, the expiration on the sessions are normally short and they expire when the user closes his browser.
Also it is recommended not to use it to store Get information like Page number, because it can't be re-referenced.
Is there a way to close a PHP session without either writing or destroying it? Am I missing something or are there just two functions (session_write_close() and session_destroy()) which reset session_status() to PHP_SESSION_NONE? In other words, if I have an open session, can I simply close it without affecting the external session data, so it can be reloaded again.
You can do this by $_SESSION = null. The session is unavailable but the data remains (does not get deleted).
Consider you have data in the session:
<?php
session_start();
session_regenerate_id(); // get a fresh id
echo session_id();
$_SESSION['test'] = '12345';
print_r($_SESSION); // echoes the data in the session
Data: test|s:5:"12345";
Then in the next request:
<?php
session_start();
echo session_id() . "<br>"; // echoes the same id as of the last request
$_SESSION = null;
print_r($_SESSION); // echoes nothing
echo "<br>";
echo session_status(); // echoes 2 (PHP_SESSION_ACTIVE)
Data still the same: test|s:5:"12345";
(php-fpm 5.4.29, most recent nginx, memcached as session handler).
Well the data still can be written through $_SESSION['whatever'] = ... but not read. I'm not sure whether this is a good solution but I have to admit I still don't understand why or whatfor you need this.
As an alternative, you could implement a wrapper class for the session with a property $this->active = true; // or false:
class MySessionWrapper {
protected $active;
protected $data;
// getter setter for $this->active and $this->data ...
public function getData($var) {
if ($this->active !== true) {
throw new Exception('session disabled');
}
}
}
Some months later after raising an issue the two new methods are now available in PHP 5.6, but the documentation arrived only with 5.6.2.
session_abort() – Discard session array changes and finish session, see the docs.
session_reset() – Re-initialize session array with original values, see the docs.
I want to change the session id once the user has logged in to a custom random session id with my own prefix.
However, when I do the below the session data is lost;
Zend_Session:setId('my-new-id');
Zend_Session:start();
But if I do the following the session data will still be available;
Zend_Session:regenerateId();
Zend_Session:start();
Anyidea how can I fix this issue?
see in library/Zend/Session.php:316:
if ( !self::$_sessionStarted ) {
self::$_regenerateIdState = -1;
} else {
if (!self::$_unitTestEnabled) {
session_regenerate_id(true);
}
self::$_regenerateIdState = 1;
}
Best practice is to call this after session is started. If called prior to session starting, session id will be regenerated at start time.
also see: Global Session Management with ZF1:
$defaultNamespace = new Zend_Session_Namespace();
if (!isset($defaultNamespace->initialized)) {
Zend_Session::regenerateId();
$defaultNamespace->initialized = true;
}
added:
Then try this:
$commit = Zend_Session::namespaceGet('Default');
Zend_Session::writeClose(false);
// ^ session_commit(); // see Advanced Usage: http://framework.zend.com/manual/1.12/en/zend.session.advanced_usage.html#zend.session.advanced_usage.starting_a_session
.. change id with session_id("my-new-id");
// start new session ...
$namespace = new Zend_Session_Namespace('Default');
foreach($commit as $idx => $data){
$namespace->$idx = $data;
}
However! after calling Zend_Session::writeClose() we cannot restart session with Zend_Session::start() version of 22744dd
see this issue:
https://github.com/zendframework/zf1/issues/159
fixed version: https://github.com/itscaro/zf1/blob/bbebe445d8551582cba6f5e9c9c1a8396fb2b322/library/Zend/Session.php#L436
anyway, I recommend watching the documentation of the start session - Starting a Session
and/or use Zend_Session::regenerateId(); instead of Zend_Session::setId()
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']);
I'm working with a third party COM object from PHP and I want to save the object on a session variable to access it in future server calls.
If I save the object in session:
$_SESSION['collItem'] = $collItem;
I can access it's methods and properties through $_SESSION['collItem'] inmediately after definition.
But, in future calls to server, if I try to use $_SESSION['collItem'], I can't access it again.
I write here some more code to clarify.
Method to initailize COM object in my script "functions.php":
public function setAppData() {
try {
$appD = new COM('ASData.CASDataApp');
$appD->InitMasterData(true, 1, 91);
$appD->DateMask = 'ymd';
$_readDB = $appD->InitApp($this->readDB());
} catch (Exception $e) {
$err = 'Connection error: ' . htmlentities(addslashes(strip_tags($e->getMessage())));
$this->setError($err);
return false;
}
$appD->appPath = str_replace('\app\include', '', __DIR__);
$this->iniciarCollections($appD);
$this->appData = $appD;
}
Call to method from my script "edit_json.php":
require_once('functions.php');
if (!session_id()) {
session_start();
}
// We recover $mbw object saved in session and initialize COM object
if (isset($_SESSION['mbw'])) {
$mbw = unserialize($_SESSION['mbw']);
}
$mbw->setAppData();
$appData = $mbw->getAppData();
$_SESSION['appData'] = $appData;
If I try access $_SESSION['appData'] inmediately after COM initialization I can work with it without problems, but if I try next code in future server calls (whith $appData object saved in $_SESSION['appData']:
if (!session_id()) {
session_start();
}
$appData = $_SESSION['appData'];
// I can't work with $appData object if I don't initialize it again
Reinitializing COM object isn't a good solution for me because I lose all changes I made.
Use session_start() at the beginning of your script. You need it to retrieve session data from the server into the $_SESSION variable.
From http://php.net/manual/en/function.session-start.php :
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.
You should edit your question and include your getAppData() method, as well, so we can do a better diagnostic. But what I can guess is that your getAppData() returns an object, and, in that case, when you have a code like
$appData = $mbw->getAppData();
$_SESSION['appData'] = $appData;
what PHP is doing is saving in $_SESSION['appData'] only a reference to the $mbw->getAppData() object, and not the real object.
If you want to store the real object in session, you would have to do the following:
$_SESSION['appData'] = serialize($appData);
and then, whenever you want to use the stored object, you would do:
if (isset($_SESSION['appData'])) $appData = unserialize($_SESSION['appData']);
on the beggining of every file that uses the $appData that was saved in the session.