I am trying to write a simple page that will save some data to the GLOBAL state (stored in server memory) using a dynamic variable name. In simple terms, there are only two parameters that can be sent by the query string (GET only).
jam: the parameter identifying a unique piece of data, which can be virtually any text string (including numbers). This value is appended to the string "jam" to create the dynamic variable name. So ?jam=123 results in global variable jam123. Likewise So ?jam=Booboo results in global variable jamBooboo.
section: the value to which the global variable mentioned above will be set (must be numeric). So if ?jam=Booboo§ion=4 is passed, the value of global variable jamBooboo is set to 4.
The idea is that once the values are set for each dynamically named jam (jamXXXX), any future requests specifying that same jam should output the set value. For instance, and requests specifying ?jam=Booboo AFTER the page is called with parameters ?jam=Booboo§ion=4, should simply output "4". But if the next request is ?jam=Booboo§ion=6, then subsequent requests should output "6".
This is set up on PHP7 on the AWS Lightsail LAMP Stack. I am open to using another variable scope if it will persist in Server memory (not a cookie).
I have tried the code below, but while I see the initial value properly when the global variable is SET, I do not see it output on subsequent requests. I am not sure if there is a missing setting in PHP, or if my code is off somehow. I have also tried using the global keyword and looking for a register_globals setting in php.ini (doesn't exist currently).
<?php
if(isset($_GET['jam']) == false){
// Do nothing, it's a bad request - jam is a required variable
}
else if (isset($_GET['section']) == false){
// section is not specified, so output the global value of jam if it exists
if(isset($GLOBALS["jam".$_GET['jam']])){
echo $GLOBALS["jam".$_GET['jam']];
}
}
else if (is_numeric($_GET['section'])){
// section is specified and its a number so set the global value for jam to that number and output it
$GLOBALS["jam".$_GET['jam']] = $_GET['section'];
echo $GLOBALS["jam".$_GET['jam']];
}
else{
// Do nothing, it's a bad request as none of the mandatory conditions have been met
}
?>
If I'm not mistaken, you seem to expect $GLOBALS to persist between 2 different PHP request.
Unless otherwise programmed, each PHP call would recieve its own memory space that DO NOT share with each another. So a variable saved to the $GLOBALS array will only be available to that request, and will be forgotten immediately when that request end. Subsequent call to the PHP code on the same server (even the same script file) do not received the $GLOBALS values from previous calls.
You need to program you persistent storage with files, cache service or databases.
Related
I'm playing with laravel/php and was using the Cache to store a specific cached variable. I wanted to avoid hitting the database for a property / setting I need all my users to rely on. This setting controls whether certain events can occur. This wasnt difficult as I could simply check if I have the cached variable and assign it otherwise get it from my backend (SQL Server):
if (Cache::has('myKey')){
$value = Cache::get('myKey');
} else {
$value = DB::table('myTable')->get();
Cache::put('myKey', $value);
}
//use cached value...
This cached value or db setting is caused by a certain action of an administrator he / she can turn this setting on (true) or off (false). However, we also have an outside process (not on the actual site but an actual sql job) that has to also set this setting. In the SQL job I can easily assign the db setting (true or false) but how do I write that setting to my cached value in laravel / php if I am inside of my sql job?
The short of this is how can I set a server side cached variable value from outside of my website?
So in that case I would either go with exposing a REST API (protected by authentication of course) that does this. Something like http://my-host/api/clear-cache.
Or ssh into the server directly and change the cache.
I'm studying a code from CMSimple 3.0 framework, with this line:
if (eregi('login.php', sv('PHP_SELF')))die('Access Denied');
So, it's suppose to display "Access Denied" if the char "login.php" is present in sc('PHP_SELF').
I know that PHP_SELF is the name of the running script (i-e the name of the page being called). But after some research I was not able to find out the role of function sc.
Any idea why?
The documentation for CMSimple tells me:
Returns the server variable $name, if it's set, the empty string otherwise.
The function sv in the version of CMSimple you're working on is defined on line 190 of cmsimple/cms.php (you'll notice that is the only script that does not throw a fatal error when called directly). Although the documented definition is quite brief you'll notice sv does a couple of things:
It creates a global variable array named $_SERVER consisting of the variables in $GLOBALS['HTTP_SERVER_VARS'], unless the array $_SERVER already exists.
The HTTP_SERVER_VARS array contains information such as headers, paths, and script locations. You will find some familiar elements in these arrays, like; PHP_SELF (which is the file name of the current executing script), REMOTE_ADDR, QUERY_STRING, and PHP_AUTH_USER. All variables that you will see sv queries for in this code base.
If/When $_SERVER exists it queries the array for a variable and returns it, unless the variable isn't set; then it returns ''.
The code you posted
if (eregi('login.php', sv('PHP_SELF')))die('Access Denied');
Is comparing the expression 'login.php' to the name of the script that is being executed and exiting with message 'Access Denied' if they match.
I am using AJAX to store the first 4 digits of a credit card in $_SESSION["first4"] number during the onBlur event. I have a sample which works flawlessly. Then I take that good code and stick it a shopping cart we purchased from Clearcart (we now own the code). The issue is that the $_SESSION variable is always empty in the AJAX php receiver program. Here is the entirety of the program:
$sessionName = "ClearCart20UserSession";
if (isset($_REQUEST[$sessionName])) session_id($_REQUEST[$sessionName]);
$started = session_start();
$_SESSION["first4"] = isset($_GET["first4"])?$_GET["first4"]:"";
After that fourth line of code the following variables are dumped: (i.e. these are output values not assignment statements)
$started = 1
session_id=4f920c1fe5e2078d95f7700ece674659
$_REQUEST=Array
(
[first4] => 5554
[PHPSESSID] => 4f920c1fe5e2078d95f7700ece674659
[ClearCart20UserSession] => 4f920c1fe5e2078d95f7700ece674659
)
$_SESSION=Array
(
[first4] => 5554
)
$_SESSION in the calling program literally contains thousand of variables. Yet, here in the receiver it is empty except for the variable I set.
Notes:
1) That is the same session_id/PHPSESSID as in the calling program - I have dumped it. (When I say calling program I mean the php program which generated the html form; obviously the actual 'calling' program is the javascript in the browser)
2) The http type and domain are identical (both are https:). I have put the receiver ajax program in the same directory as the caller just to eliminate any cross-domain issues.
3) The session save path is /tmp and when I look in that folder the sess_4f920c1fe5e2078d95f7700ece674659 file exists. (Although it seems smaller than I would expect with thousands of variables).
4) When I go back a page in my browser and then forward to re-show formerly saved session variables (i.e. things like form input values) they still exist so the AJAX recipient is not clearing $_SESSION as the empty array might imply.
5) The shopping cart uses cookies and the cookie values are correctly reflected in $_REQUEST as expected.
6) I added session_write_close() to the end of the main/caller program to ensure the session file is not open. Should not matter as the caller php terminates and nothing happens till the javascript event fires AJAX.
7) FWIW session.upload_progress.enabled is on.
8) Curiously the shopping cart uses AJAX for its own purposes which I believe is working fine. Regardless, I don't see how that could impact me - its completely different AJAX called and received by different javascript and php respectively.
9) As mentioned above, this virtually identical code works in a test sample I developed where I even mimic using cookies.
10) I have read several dozen postings on this issue but none have fixed my problem. Most seem to be related to not using session_start or having the right session_id.
What else can I try?
Found the problem: the shopping cart software changed the session folder with this line of code:
session_save_path("tmpsession");
Hence, even though the session_id's were identical the session files were stored in two different folder locations (the AJAX file was in /tmp and the main calling program was using www/tmpsession).
So I have this piece of code that is executed each iteration. The iterations are not ordinary loops but part of a series of ajax request iterations. The first ajax request determines a filename that is assigned to e.g $_SESSION['filename'] and then this variable is pushed into and array etc. Now the problem occurs when i have multiple files being processed.
It happens often that one of the filenames that is generated gets duplicated and inserted into the database which it should not.
First callback function:
case 'upload':
...
$_SESSION['upload_filename'] = random_filename($alphas).'.'.$fileExt;
...
break;
second callback function:
case 'insert_db':
array_push($someGlobalArray, $_SESSION['upload_filename']);
insert($_SESSION['upload_filename']);
break;
So as I said a new filename is generated properly like 70% of the time. I'm not sure why the old filename from the previous "iteration" lingers and $_SESSION['filename'] does not contain a new filename. I've tried unset the filename after insert() in the second callback function, but that causes a problem where no filename is available to be either pushed into the array or inserted into the database since what I think is that it gets unset before? I've also tried sleep(2) after the insert() and then unset but does not help.
Here is more of the code: http://pastebin.com/g4fereQx
My best guess is that your code may not be executing the the exact order you think it is.
Its hard to say with the snippets you've posted though.
could you show a little more of your code, like the ajax calls that send off the data and such. I know I've had problems in the past where I wasn't setting async: false in my ajax call and so it would try to process and act on information that hadn't properly been set yet
There is a php file (current.php) with some variables, like:
function do() {
$var = 'something';
}
And one more php file (retrieve.php), which is loaded to current.php with jQuery ajax .load().
The problem is - retrieve.php doesn't see $var.
Tryed this (inside retrieve.php, shows nothing):
global $var;
echo $var;
How to fix?
Thanks.
Some things you must be aware of:
When you use PHP, you do not download a file: you execute a script and retrieve its output.
PHP variables are destroyed when the script ends. You cannot share variables between two scripts unless you store them somewhere (e.g., in a database or session file).
PHP variables are local to the function where you define them, unless you issue a global $foo; statement inside the function.
jQuery is a JavaScript library. JavaScript and PHP are different languages: they cannot see each other variables.
Said that, I suggest you reconsider your question and try to explain what you need to accomplish rather that how you want to implement it.
The problem is - retrieve.php doesn't see $var.
Sure it is!
all current.php variables are long dead along with current.php itself, which was run, print some HTML and die.
you have to pass required value using standard HTTP mechanisms. you know - GET, POST etc.
If you want the script you load through AJAX get the value of the vars from the page initiating the AJAX load then you either have to pass the values when loading the AJAX script or store them somewhere temporarily (in DB linked by session ID, or in a session var) so you can retrieve them easily.