I'm writing a web application in PHP and I want to declare an array, in which i want to save the host and how often this host has opened my web application. I want to add the variable to something like the application scope in JSP. I've tried to add this array to $_SERVER, but this hasn't worked. If I try to acess the variable in another file with $_SERVER[$_GET["id"]] the variable is always NULL. Can someone please help me?
Here my code:
if(empty($_SERVER[$_GET["id"]])){
$_SERVER[$_GET["id"]]=array($country, 1);
}else{
$_SERVER[$_GET["id"]][$country]+=1;
}
several things:
$_SERVER is for SERVER do not use it to play global array.
$_SESSION is returning null because you probably didn't declare any
session_start at the beginning of your file. If you don't do that, the session cookies (variables) are not shared and this is why its null.
this is the basic of vanilla php.
From here, you could explore a micro framework that has this built in...
UPDATE
due to your misconception of "session", what you want to do is to persist data. If you want to "share" this array of yours among different users (aka data sharing among session), I would recommend to persist via data storage:
sqlite/memory or sqlite/file
redis (value/key and its quick)
mysql or any sql/no-sql
least favorable IMO: write to a simple file and retrieve. The only issue with this, is that you will have "lock" condition but then again so will the other ones
Related
Is there a way in PHP to use "out of session" variables, which would not be loaded/unloaded at every connexion, like in a Java server ?
Please excuse me for the lack of accuracy, I don't figure out how to write it in a proper way.
The main idea would be to have something like this :
<?php
...
// $variablesAlreadyLoaded is kind of "static" and shared between all PHP threads
// No need to initialize/load/instantiate it.
$myVar = $variablesAlreadyLoaded['aConstantValueForEveryone'];
...
?>
I already did things like this using shmop and other weird things, but if there is a "clean" way to do this in "pure PHP" without using caching systems (I think about APC, Redis...), nor database.
EDIT 1 :
Since people (thanks to them having spent time for me) are answering me the same way with sessions, I add a constraint I missed to write : no sessions please.
EDIT 2 :
It seems the only PHP native methods to do such a thing are shared memory (shmop) and named pipes. I would use a managed manner to access shared objects, with no mind of memory management (shared memory block size) nor system problems (pipes).
Then, I browsed the net for a PHP module/library which provides functions/methods to do that : I found nothing.
EDIT 3 :
After a few researches on the way pointed out by #KFO, it appears that the putenv / setenv are not made to deal with objects (and I would avoid serialization). Thus, it resolves the problem for short "things" such as strings or numbers but not for more large/comples objects.
Using the "env way" AND another method to deal with bigger objects would be uncoherent and add complexity to the code and maintenability.
EDIT 4 :
Found this : DBus (GREE Lab DBus), but I'm not having tools to test it at work. Has somebody tested it yet ?
I'm open to every suggestion.
Thanks
EDIT 5 ("ANSWER"):
Since DBus is not exactly what I'm looking for (needs to install a third-party module, with no "serious" application evidence), I'm now using Memcache which has already proven its reliability (following #PeterM comment, see below).
// First page
session_id('same_session_id_for_all');
session_start();
$_SESSION['aConstantValueForEveryone'] = 'My Content';
// Second page
session_id('same_session_id_for_all');
session_start();
echo $_SESSION['aConstantValueForEveryone'];
This works out of the box in PHP. Using the same session id (instead of an random user-uniqe string) to initialize the session for all visitors leads to a session which is the same for all users.
Is it really necessary to use session to achieve the goal or wouldn't it better to use constants?
There is no pure PHP way of sharing information across different
threads in PHP! Except for an "external"
file/database/servervariable/sessionfile solution.
Since some commentators pointed out, that there is serialize/unserialize functionality for Session data which might break data on the transport, there is a solution: In PHP the serialize and unserialize functionality serialize_handler can be configured as needed. See https://www.php.net/manual/session.configuration.php#ini.session.serialize-handler It might be also interesting to have a look at the magic class methods __sleep() and __wakeup() they define how a object behaves on a serialize or unserialize request. https://www.php.net/manual/language.oop5.magic.php#object.sleep ... Since PHP 5.1 there is also a predefined Serializable interface available: https://www.php.net/manual/class.serializable.php
You can declare a Variable in your .htaccess. For Example SetEnv APPLICATION_ENVIRONMENT production and access it in your application with the function getenv('APPLICATION_ENVIRONMENT')
Another solution is to wrap your variable in a "persistent data" class that will automatically restore its data content every time the php script is run.
Your class needs to to the following:
store content of variable into file in __destructor
load content of variable from file in __constructor
I prefer storing the file in JSON format so the content can be easily examined for debugging, but that is optional.
Be aware that some webservers will change the current working directory in the destructor, so you need to work with an absolute path.
I think you can use $_SESSION['aConstantValueForEveryone'] that you can read it on every page on same domain.
Consider to refer to it's manual.
I am used to use Java and Spring Framework. But not so long ago I started learning PHP , to get familiar with another kind of language.
I am trying to write a simple thing for drawing using html canvas, so more then 1 user can use that at the same time to draw.
In Java i would use a class variable in controller to store the picture draw by users. And every 1-2 seconds users send the request with the new data they have drawn, so i can add the changes to the global variable. and then send the changes to every user. When a new user enters, the server sends the whole picture to him.
So, my question is, how can i store an application global variable in PHP? like in this example with picture...
As i see, after finishing, the PHP halts and all the variables die with it, right? So is there any way to make a variable application global? So i can get access to it from different parts of application?
I can save it to text file before finishing the script. and every time new request happens, read it again from text file, make changes and then write back to text file... but it's so crazy... isn't there any way just like in Spring Framework and Java that i used before?
You need a form of persistent storage. By persistent, I mean storage that is not based on an individual user's session like the $GLOBALS array is. PHP Sessions are useful for storage for a single user, but one user cannot access the session data of another user.
Persistent storage can be achieved a few ways. Some options: checking a row in a database table or storing a value in a file like you mentioned.
Database storage
Check out php's mysqli_query() for more information on doing this via a database. This will require knowledge of MySQL syntax.
File storage
Check out php's file_get_contents() and file_put_contents() for examples on how to easily interact with retrieving data from files and setting data in files.
As DevZer0 answered - you want to use sessions. More information about session you will find in the php manual: http://www.php.net/manual/en/intro.session.php
what I am trying to find out is, if I can share a Session variable for multiple clients.
Like they can use the exactly same Object. The below example will illustrate what I would like to do.
client1:
start_session();
include('somelcass.php');
//some code...
$someobj = new someclass();
$_SESSION['myobject'] = serialize($someobj);
$id = sha1("somephrase");
set_session_var_for_other_users_by_id('myobject', $id);
client2:
start_session();
include('somelcass.php');
$id = sha1("somephrase");
get_sessionvars_from_other_users($id);
$someobj = unserialize($_SESSION['myobject']);
//now use someobj from class someclass
And my additional question is:
Do you recommand using some session extention like: sessionPsql
Answering your last question first:
The Session PgSQLDocs you linked is the PostgreSQL Session Save Handler. It is a Session Save Handler you can configure to use instead of the default session save handler. The default session save handler in PHP is storing sessions to disk (files). If you use the save handler for PostgreSQL sessions are saved into a PostgreSQL database instead (pgsql).
Saving sessions inside a database can make sense if you want to allow access to the session store from multiple webservers (scaling an application) or in your case (probably) to access all sessions with SQL queries albeit normally a tailored session save handler is defined for that (which could be based on the PgSQL session save handler functions).
To answer your first question then:
Yes you can do so as long as you've got a reference to the object you relate to and you know how to access it. This can be either done by manually accessing the session storage or by sharing a session on it's own and switching sessions to access other session data. It depends on your needs, in your case it's probably more easy to just access serialized data that is stored by the ID in some extra table that has nothing to do with sessions. You should think about how to take care of the data if you don't need it any longer, e.g. remove it after some time of inactivity. In the end you're writing your own session implementation that way which is do-able. PHP before version 4 had no session support out of the box and the session support it has nowadays is very lightweight so if you need to do more specific stuff like you need to do, you normally write your own.
So multiple clients can use the same session (share a session) which is actually as well a way to attack webapps (session hijackingAttack) but as long as the "hijack" is intended inside your application data-flow, I do not see anything technically wrong with it. In PHP that means you need to close the current session, open the other one (sessions are identified by their name and ID), read the value, close the other session and re-open the current one. It technically works in PHP however write solid code when you do this because session problems are quite hard to debug.
This is also often a good reason to write your own object-sharing mechanism between multiple clients instead of re-using PHP's session featureDocs for that.
Multiple clients can't share data in the session object. If you want to share data between clients, you would normally use some other means of server side storage e.g. A database.
I have written a solution for PHP applications to resolve mainly 2 types of problem:
How to share data/variables between PHP Process, hosted on same/differents servers
How to synchronize read/write operations in data/variables
My Project is hosted in GitHub ANYEM Project
First : Start the ANYEM_SERVER using command line
php ANYEM/ANYEM_SERVER/anyem.app.server.impl/ServerImpl.php
Now, in your PHP Application you can do as follow:
<?php
// load server's connection configuration (ANYEM_SERVER IP and Port Number ...)
$clientConnection = ClientConnectionImpl::newClient();
// build a key for your variable that will be stored in server
// the key is composed on 3 Parts : [1] => URL, [2] => Variable Namespace, [3] => Variable Name
$identifier = new ResourceIdentifierImpl("anyem.com", "anyemNameSpace", "a");
$a = 5;
$anyemClient = new AnyemClientImpl($clientConnection, $identifier);
try {
// if $a is reserved by another PHP Process, so this process
// will sleep (1/10) seconds and retry the reservation of the resource
// here, the max number of reservation attempts is 5, if reservation
// fails, an Exception will be thrown
$responseWrapper = $anyemClient->get($a, 5, 100000);
// here we have reserved the variable $a, and we have the unserialized contents
$a = $responseWrapper->getResource()->getData();
// here, we update the contents, send it to ANYEM_SERVER and releasing the lock (we unreserve it)
$anyemClient->put(++$a);
}
catch (Exception $e) {
print $e->getMessage() . "\n";
continue;
}
Hope that can helps someone :)
I think best solution for this problem is using database. Create a table and store in it. When you need just read data from table. it is fast and easy solution to share data between sessions.
I have a cluster of PHP hosts serving a small PHP script. The script retrieves an array of key/value pairs from the database at the beginning of the script, that are configuration values.
I would like to avoid the retrieving of these configuration data from the database for every request, in order to optimize.
My idea was that the script loads the data from the database only for the first request and it stores these variables into some kind of shared memory that is persistent among all sessions.
I've tried to use PHP global variables but they are all destroyed at the end of the script...
Also, I would like to avoid using a config file because as I said I have more than one host serving the script and I'd like to store the data centralized.
When I need to store small bits of data across scripts, I usually use apc
apc_add('config', array('a' => 'b'));
$config = apc_fetch('config');
...among sessions
rather implies that you are already using sessions - so why not just use a custom session handler?
You load the session data using the session id, and overload the config. Optionally you could set it up so you can call the read method and only return the config data without searching for conventional session data.
Probably the most efficient way to do this would be to run a daemon - that way you can keep the config data in PHP variables. There's a nice single threaded server implementation here.
You can keep this as:-
$_SESSION['_config_data']['index_1'] = 'value_1';
$_SESSION['_config_data']['index_2'] = 'value_2';
$_SESSION['_config_data']['index_3'] = 'value_3';
...
In this way, you will get all the configuration data stored in the session variable "$_SESSION['_config_data']".
But you need to check at the starting of the setting method, whether the session variable "$_SESSION['_config_data']" exists with some pre-filled data or not. If it is, then you don't need to set the configuration data for each page request.
Hope it helps.
Answer is memcached: http://memcached.org/
Its a sort thing that was meant to for this kind of scenarios and there are alot of good tutorials but official php documentation is a good starting point: http://php.net/manual/en/book.memcache.php
Does PHP have global variables that can be modified by one running script and read by another?
No, by design PHP is a "share nothing" architecture, which means nothing is shared between processes running at the same time or between requests running one after another. There are ways to share data, but you have to do it explicitly.
If you just want to share between 2 requests from the same user, sessions or cookies might be the way to go.
If you want to share between multiple users, you probably want some sort of shared persistence, either short term in a cache (eg. memcached) or more robust like a database.
Either way, the data is actually being retrieved and reconstructed on each request. It's just handled automatically for you in the case of sessions.
You can actually do this using shared memory, or APC (which is using shared memory itself).
You can use $_SESSION, i.e.:
script1.php
<?php
session_start();
$_SESSION['myVar'] = "something";
?>
script2.php
<?php
session_start();
echo $_SESSION['myVar'];
//something
?>
The only one which could be accessed between scripts is the superglobal $_SESSION array. This is because whatever you store in the array is sent to a cookie, which can then be picked up by the next PHP script.
Global variables simply mean that they can be accessed in the script regardless of the scope; that doesn't mean they can be sent between scripts.
So either you have to transfer the variables using the $_SESSION array (this stores a cookie on the client computer, so don't sent any sensitive information through that array) or you can either POST or GET between the scripts to send the variables.
Each request is handled by a php instance of its own. Global variables in php are only accessible from within the same php instance. However you can use something like the memchached module to share data between different instances (which should usually be faster than writing the data to the filesystem).
Not as such, but you can use cookies or sessions to maintain data for duration of a user's browsing experience, or you can write to a database or file on-disk if the information needs to persist beyond that.
Another common substitution for global variables in PHP is the shared use of a database like MySQL (albeit not a perfect one)
Global variables are bad in most programming. They're especially bad in multithreaded/multiuser systems like webapps. Avoid. If you must use global variables (rather than global constants) put them in a database with transactions guarding updates.
Since you talk about different scripts though, it sounds like what you really want is a web application framework in a more application oriented language --- something like Django (python) or Rails (ruby). These let you think of your code much more like a cohesive PROGRAM, rather than a lot of loosely connected scripts that process web requests.
I made a tiny library (~2 KB; <100 lines) that allows you to do just this: varDx
It has functions to write, read, modify, check and delete data.
It implements serialization, and therefore supports all data types.
Here's how you can use it:
<?php
require 'varDx.php';
$dx = new \varDx\cDX; //create an object
$dx->def('file.dat'); //define data file
$val1 = "this is a string";
$dx->write('data1', $val1); //writes key to file
echo $dx->read('data1'); //returns key value from file