I'd like to completely disable PHP sessions, but transparently to code.
That is, make it so that session_start() returns successfully, and $_SESSION exists, and works within a single request in the sense that a single request can read/write from that global, but then that data is thrown away at the end of the request, no session variable is passed or cookie'ed, PHP doesn't attempt to store it on disk or anywhere else, etc..
I read in one place that using the file session-handler with a gc_lifetime of 0 works, but elsewhere saying that doesn't work. And I wonder whether there's a no-op "handler" or similar thing that's the best/correct way to do this.
I prefer a solution using only php.ini, but an in-PHP solution is acceptable if that's the only way?
how about using auto_append_file directive in your php.ini file:
http://php.net/manual/en/ini.core.php#ini.auto-append-file
then adding the kill code session_destroy() \unset in the append file
PHP allows you to plugin a SessionHandler which is responsible for storing and loading the sessions. You can disable session retention by making all of the session handler functions NOPs. Users will still receive a session cookie (because PHP doesn't know any different), but that may be acceptable, depending on your use case.
Use auto_prepend_file to set up the session handling before any code is run that makes use of sessions.
Related
I've always wondered why PHP makes you manually session_start() in order to gain access to the immensely useful $_SESSION "super-array".
It strikes me that this might be causing a lot of stress on the server, but not really make a difference in practice unless you have an extreme amount of users.
I don't really see why it would cause such a strain, though, if you don't use that array/mechanism. And if you do, you always want session_start() to have been called... It would really be nice to finally get this straightened out.
The manual doesn't offer any explanation: https://www.php.net/session_start
It's not really a question of how much overhead it causes, as far as why sessions aren't started by default. There are tons of possible PHP applications that have nothing to do with session variables (including any CLI use!), and therefore, on principle it shouldn't be automatically started. Establishing an idle database connection ("immensely useful!") also doesn't create silly overhead. It's still not done by default. Resources should be available, but uninstantiated.
The main performance impact caused by starting a session, with or without ever using it, basically involves (quoting from the manual on session_start()):
PHP will call the open and read session save handlers. ... 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.
This typically means disk access to look up and read the serialized session data. Even if it's empty or non-existent. (It will not be created until $_SESSION variables are used; but you won't know if it's there without trying!) Also: your session ID is typically stored in a cookie. Want session? Make a cookie, take a cookie, pass a cookie, read a cookie, etc. pass/read on each page load. Unnecessary baking and trading, and we'd rather avoid redundant HTTP traffic.
Aside that, there's a strange and wonderful thing called session locking that can make you scractczch your head a lot and wonder why you can't load long-running scripts on your site in two tabs simultaneously, even when you've double-damned-configured your Apache, MySQL and the rest to handle concurrent connections and/or space alien armadas on steroids. Without session locking, you could. (Alas, debugging long-running scripts with sessions on!)
Significantly, this will haunt you with concurrent AJAX requests to PHP scripts with sessions; they'll be sequentially processed instead. There are ways to overcome session locking delays, but the default behavior blocks parallel execution, and requests are queued, and it's rather annoying but a necessary evil to prevent race conditions and session corruption (read more).
So much for the obvious performance/quirks side. In terms of customizing how things work, there are functions that may be called before session_start(), such as session_name() (for named sessions). The session_start function itself (as of PHP 7) takes an optional array of session parameters which you couldn't use, were the session started by default.
If you look at the link above, you'll notice that there is in fact a session auto-start option in php.ini session configuration:
session.auto_start boolean
session.auto_start specifies whether the session module starts a session automatically on request startup. Defaults to 0 (disabled).
There are some related cautions in PHP Intro to Sessions on the auto_start option:
Caution If you turn on session.auto_start then the only way to put objects into your sessions is to load its class definition using auto_prepend_file in which you load the class definition else you will have to serialize() your object and unserialize() it afterwards.
If you are certain that you always want to use sessions, the simplest move would be to create a bootup file that you require at the beginning of files that use sessions; add the path to the file into your include path; and then simply <?php require 'sessions.php' before your main code begins.
The session bootup file could also have some of your own session-handling functions, etc. relevant standard material. This route would give you more freedom than the auto-start option, plus a way to implement other options and functionality across all your session-using code. You shouldn't rely on the auto-start in any case, in case you ever want to create code that can be easily deployed into environments with default PHP configuration!
GOAL: To have a global variable that any php on my website can access. The variable would be a bool.
What I am stuck on is how I can store such a variable that is available to all php scripts, but can also be updated via php.
The variable is a bool that determines whether or not the site loads advertisements based off if a certain criteria was met that day. So, every day I will have a cron job that runs to reset this variable, thus meaning the variable needs to be update-able via php.
The only way I can think of to store it is either via a db table, which seems like overkill just for one little bool, or a json file that I store outside of the public_html directory.
With the json file, I would just perform a get on load with file_get_contents via my "class lib" file that is present on all pages of the site. Then do something similar to update it with the cron job.
NOTE: I do have a php file that is present on ALL of my pages, so including a file on every page is not a problem.
Is there a better way? It would be nice if there was a way I could just set a PHP superglobal or something, but I'm unsure if settings something like $_SERVER['custom-variable'] sticks or if it's just for that session.
Apologies if this is a simple mis-understanding of how PHP superglobals/constants work.
I appreciate any help.
A couple of options:
Just store it in the database. This is a perfectly reasonable solution.
Store it in a file, in whatever format you want. JSON is handy if you want to store anything more complex than a single string or number.
Store it in a PHP file which returns a value, e.g.
<?php return array("ads_enabled" => true);
then require() that file -- the require() call will return that value. If your server has a PHP opcode cache enabled, this will be faster than loading a normal file, as the contents of the file will be cached.
Note that the file cannot return false, as that's indistinguishable from the include() failing.
The following are not viable options:
Storing it in a session. Sessions are per-user, and start out empty.
Storing it in an in-memory cache, like APCu or Memcache. Caches are not persistent storage; the value may be evicted from the cache.
Storing it in an environment variable. Environment variables are awkward to update in most server environments.
SetEnv APPLICATION_ENV "development"
Use that in your Apache vhost definition if you are using Apache and have access to modify it. I think you can do something similar in .htaccess files.
You can use a .env file and a library for reading that file.
If you are using a front controller where all requests pass through a single index.php file then you can set a global variable or constant in there.
Why I can use setcookie without any preparation while need a session_start() before using $_SESSION?And I think works they do are similar.
Because setcookie() defines a cookie to be sent along with the rest of the HTTP headers. That's a completely different thing than what session_start() does, e.g. creating a session or resuming the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
The first just adds something to the header and sends it to the browser, while the other gets the Session ID from $_COOKIEs or $_GET or $_POST and then tries finding the session file in the session_save_path and when found unserializing the values of it into $_SESSION and if not, create a new session, probably using setcookie in the process to set the Session Id.
See the chapter on Sessions in the PHP Manual.
Edit Like #Felix correctly points out below, the session is not necessarily saved in a file. It's not that important though, because the argument stays the same: session_start will find and (re-) initialize your session data, while setcookie just does what the name implies.
For explanation see the reply before mine.
If you just don't want to call the start_session() function have a look at this setting in the php.ini:
session.auto_start
The session data is not necessarily stored in a file as Gordon says. With session_set_save_handler() you can define your own backend that should store the values, e.g. in a database.
All this data retrieving is handled with session_start(). This way you can easily change you backend without breaking your application.
Note: This is only one reason for session_start(), and again it does lot more then just setting cookies.
The session data is not necessarily stored in a file as Gordon says. With session_set_save_handler() you can define your own back end that should store the values, e.g. in a database.
All this data retrieving is handled with session_start(). This way you can easily change you back end without breaking your application.
Note: This is only one reason for session_start(), and again it does lot more then just setting cookies.
On both Chrome & Firefox, this lasts for about an hour then the session cookie, and other cookies set by javascript disappear. I didn't even close the browser.
session_set_cookie_params(946080000); // 30 years
session_start();
$_SESSION['login']=true;
Gone. The session cookies are gone. I assume its not a browser thing because it disappears on both Chrome & Firefox. I didn't test on IE.
Is this normal behavior... I'm certain it is not being unset somewhere.
Sorry, I know I haven't given much info, but that's because there is not much info to give. It should work and it doesn't.
I think you are doing it wrong, if possible change php.ini to reflect the coockie duration you want to apply. Reading from php.net manual:
"Set cookie parameters defined in the php.ini file. The effect of this
function only lasts for the duration of the script. Thus, you need to
call session_set_cookie_params() for every request and before
session_start() is called.
This function updates the runtime ini values of the corresponding PHP
ini configuration keys which can be retrieved with the ini_get()."
This means you need to call it EVERYTIME in all your php file before you do a session_start(). A blog post that may have the solution: http://blog.centresource.com/2006/05/23/php-session-lifetime-an-adventure/
To change the value in PHP ini use following line:
php_value session.gc_maxlifetime "946080000"
Anyway its better to use a coockie, sessions aren't used for a long lifespan, rather use cookies instead.
I have integrated WHMCS and Drupal. However, when you go to Drupal and you print_r the SESSION, you see completely different information than what you would do if you go to the WHMCS pages. So, my question is, how do I access the one's session, from the other one?
I need to access it, in order to see if the user is logged in or not.
The values you'll get depend on the session.name directive in php.ini. If you want them to be able to read each others', then set the same session.name.
Or rather, session data will be loaded based on the identifier in the cookie with the same name as session.name. This defaults to PHPSESSID, but you can change it yourself.
You can set this at runtime using ini_set() or session_name().
Drupal register its own session handling functions through session_set_save_handler() during bootstrap (drupal_bootstrap()). It also sets it own session mame in conf_init().
Because of the Drupal's handlers, restoring the WHMCS' session name before using standard PHP session will not work. PHP will use Drupal's hanlder to open, read, write, etc. session information. All you will get is the data for a wrong Drupal's session returned from sess_read() when called by PHP.
One way to read WHMCS' session is to figure out how it is stored and to access it without using PHP's sessions functions.
Another way may be to undo what Drupal has done (changing session name and registering handlers) to restore default behaviors of PHP's session functions, read the WHMCS' session and restore Drupal's session name and handlers.