Why is PHP varible still undefined? - php

I am working with three PHP files. Two serve as web pages and the other in an external server side script. The server side script is included in both web pages files and what I want to do is have some buttons on the first page and depending on which one is clicked, populate the second page with data and then redirect to it.
With the code below, the idea was to pick up the button click, figure out which button was clicked, and then call the function to run the proper query and set the needed variables. I don't understand why the variable is not getting set.
Thanks to anyone looking at this!
First page's button (index.php):
<input type="submit" id='details' name='details' value='Submit'/>
Second page where variable is undefined when page is loaded:
<h4><?php echo $selected_button; ?></h4>
External script:
function detailBuilder(){
$selected_button = "Option One";
//header('Location: details.php'); if this is here, the page still redirects but the variable doe not get set
//More will happen here once it works
}
if(isset($_POST['details'])){
detailBuilder();
header('Location: details.php');
}

As several people have pointed out previously, you redirect to another file. At that point, all locally defined variables are gone - you no longer have access to them.
Look into PHP sessions in PHP's documentation. Sessions will allow you to transfer these variables from request to request. However, sessions will only work if you are running some form of webserver.
UPDATE: Also to note, as other people (once again) have pointed out, $selected_button = "Option One" will ONLY apply inside the "scope" of the function detailBuilder. So calling detailBuilder() creates a variable called $selected_button inside the function, and then immediately discards it.
UPDATE 2.0: Sorry for so many updates. Here's an example of setting a session:
Update 3.0: updated code slightly
First things first. Make sure you start the session.
session_start();
You're going to have to call session_start() at the start of any php script! That means that the first file that executes every time should have session_start() at the top.
External Script:
$_SESSION["selected_option"] = "Option One";
Script where originally it was undefined:
$selected_details = $_SESSION["selected_option"];
?>
<h4><?=$selected_details?></h4>

Related

What is the output of this PHP code during the first and second requests?

This is most likely a PHP noobie question.
To test some server caching configuration, I added the following code to my test suite:
<?php
if (array_key_exists('visited', $GLOBALS))
{
print_r("We have already met");
} else {
print_r("Hello ShimmerCat");
}
$GLOBALS['visited']=1;
?>
I'm expecting this code to take differents path of the branch during a first and second request, but it is returning the second message always. How can I achieve what I want?
PHP itself is stateless, meaning every time a user visits a PHP page, the whole operation is done from scratch with each variable being defined as in the script.
If you want to store data between views, the basic way is with cookies. If you want the details of what's remembered to be secure, use session cookies.

PHP session not working when script included in SHTML pages

Just a newbie here so please pardon my mistakes.
I'm working on a website using .shtml pages (SSI).
I'm trying to include a PHP script into my .shtml page.
Up to this point everything is working fine:
PHP script gets included and it does what it was intended for.
Here is the actual example.
There is the home page (index.shtml) including a script called security_check.php with this directive:
<!--#include virtual="includes/security_check.php?idOp=000&idPage=0000" -->
This is the PHP code for security_check.php:
<?php
session_start();
include('config.php');
include('myfunctions.php');
include('security_functions.php');
$idOp = $_GET['idOp'];
$idPage = $_GET['idPage'];
$allowedReferer = array();
// Connection to the database (defined in myfunctions.php)
$link = DB_Connect($DBhost, $DBuser, $DBpass, 1, $DBname);
// Check if the PHP session already exists. If not, create one
// (that is insert a record in the DB and returns the id, which
// will be stored in the PHP session variable).
// user ID is 0 because not logged yet
if (!isset($_SESSION['idSess'])) {
$_SESSION['idUser'] = 0;
$_SESSION['idSess'] = create_session(); // security_functions.php
}
// Please note that create_session() correctly use $_SESSION['idUser']
// in order to do its work, even if it's not passed as a parameter
// (as it should be: $_SESSION is a superglobal!) and the same goes
// for activity_supervisor().
// Defined in security_functions.php:
// it uses both $_SESSION['idUser'] and $_SESSION['idSess']
activity_supervisor($idPage,$allowedReferer,2,$link);
mysql_close($link);
?>
At this point,
home page is correctly displayed and there is a 'Sign up' button
in it, calling sign.shtml.
This sign.shtml page include the very same security_check.php script
with the exact same include directive already seen above except for the value of idPage parameter which in this case is 0001.
I would expect the script to recognize the PHP session and therefore
not creating a new session, but indeed a new session gets created every time.
I already read every other post related to PHP sessions not working and I even tried the solutions proposed there.
- session_start() is written on top of every script because there is just one script
- session.save_path equals to /var/lib/php/session and is writeable by the web server
- I already tried to set session.gc_probability = 0 and restarting the web server (to no avail, so I got back to session.gc_probability = 1)
- I tried with different browsers (namely, Firefox and Chrome) with the same results
So I tried the following test (note those two empty lines BEFORE session_start(): I always space instructions this way to improve readability)
creating a simple test.php script
<?php
session_start();
if (!isset($_SESSION['foo'])) {
$_SESSION['foo'] = 1;
echo ('Value is '.$_SESSION['foo'].'<br/>');
echo ('Refresh');
}
else {
$_SESSION['foo']++;
echo ('Value is '.$_SESSION['foo'].'<br/>');
echo ('Refresh');
}
?>
Well, believe it or not, every time I hit 'Refresh', the value
is incremented, so PHP recognize the session (the test.php script is inside the same domain as the index.shtml and sign.shtml pages).
I even tried to make the PHP script to show a link to a .html file (not .shtml) which then show a link to test.php. It works correctly!
It really seems that the session is not correctly set only when the PHP script is included into the .shtml page, even if I don't see any reason for that. Maybe you know why and, above all, how to circumvent this boring behaviour? Is it a feature? Does it depend on a parameter setting in php.ini?
Final tips:
OS: CentOS 6.3 with 2.6.32-279.el6.x86_64 kernel
Server version: Apache/2.2.15 (Unix)
PHP 5.3.3
Server is mine so I can configure everything, if needed.
Thanks in advance and forgive me for the long post: I tried to make it
clear that PHP sessions do work perfectly in every other situation I know of.
I don't think this will work because the SSI will execute the PHP script, and then send out its output to the web server. You would need some way of rewriting URLs so that they do not rely on cookies, since cookies get "eaten" before the server gets to send them to the browser.
Try using
ini_set("session.use_cookies",0);
ini_set("session.use_trans_sid",1);
and then you'll need to send the SID in the outgoing URLs (and on POST pages, too). See this answer for example.
Specifically, you need to redirect the user not to sign.shtml but to something like
$sidkey = session_name();
$sidval = session_id();
print "sign up: here";
and include this in the SSI output.
UPDATE: the root of the problem is that the SSI cannot create a session (cannot send anything but plain HTML. Sessions that use cookies rely on headers, not HTML only). But if you create the session with a PHP script launched outside SSI, that is able to set a cookie, from that point onwards all PHP scripts (whether SSI or not) are able to read the cookie and therefore will be able to access and modify the session (which is a file/memory/Redis/other on the server identified by the session cookie's value).
You can check whether a cookie is set in SSI, and if it not, you can redirect to a pure PHP page that sets the session cookie and sends back to the original shtml using a HTTP Redirect.

Trouble with calling session_start() at the start of all PDO pages

Most of my pages use Sessions, but I'm switching to PDO and calling session_start() at the start of every page is causing problems with passing headers. I've done several hours of research and am still unclear what to do about it.
Edit - What I've been doing: The 1rst line of the sign up/sign in documents as well as auth.php is session_start();, and the 1rst line of all pages the user visits subsequent to sign up/sign is require_once('auth.php');
I'm currently passing the user id to every page with $_SESSION['SESS_USER_ID']
When they sign up/sign in I connect it like this:
$member = $stmt_user->fetch();
$_SESSION['SESS_USER_ID'] = $member['user_id'];
And on every subsequent page I call it like this:
$user_id = $_SESSION['SESS_USER_ID'];
As per the manual
As of PHP 4.3.3, calling session_start() after the session was
previously started will result in an error of level E_NOTICE. Also,
the second session start will simply be ignored.
Does this mean that I no longer need to call it on every page and can just call it once when the user commences a session?
If not, what is the simplest way to do deal with this issue?
If you are using a framework, you likely just need to call it once in that framework. If each of your requests go to different php pages, then you need to make sure it gets called at least once per request (preferably as soon as possible).
You need to make yourself a bootstrap file.
A file with all common operations performed on the every page - session start, connect to database, set global variables, etc.
And then include this file into every script called.
So, you'll be sure that you have everything you need, yet called everything once.
Though I don't understand what does this question to do with PDO (as well as a previous one).
PDO is just a database driver and have not a slightest relation to headers, sessions and the like.
You can use ob_start and ob_end_flush to buffer your outputs, so you can actually do this:
<?php
ob_start();
echo '42';
session_start(); // still works because output is buffered
ob_end_flush();
?>

How to access offsite referer (and first page visited on site) via PHP on Wordpress site

I'm trying to get three things into a hidden form field in a Wordpress page:
The last "offsite" page visited before someone visited any page on my site (e.g., quite possibly a Google page)
The first page they visited on my site
The last page on my site before they went to the form page
The third one is easy (just use ), but the first two are giving me problems.
I'm trying to save #1 and #2 by using session variables, so that on every page, in the header, I have the following code:
<?php
session_start();
if (! isset($_SESSION['offsite_referer'])) {
$_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER'];
}
if (! isset($_SESSION['first_page'])) {
$_SESSION['first_page'] = $_SERVER['REQUEST_URI'];
}
?>
Then further down I have, as test code (to be changed to input type=hidden etc. later):
<p>offsite_referer: <?= $_SESSION['offsite_referer'] ?></p>
<p>first_page: <?= $_SESSION['first_page'] ?></p>
(FWIW, I also have session_start() at the top of my wp-config.php. Yes, my site has register_globals turned off.)
For some reason, $_SESSION['offsite_referer'] always ends up as my home page, even when I hit the form page (/free-reports) directly via link from another site. Similarly, first_page always shows up as /
Yes, I'm clearing all my cookies etc. between attempts, to force a new session to be created.
This code used to work fine on my pre-Wordpress site, so I can only think it has something to do with WP, specifically perhaps WP's redirection (WP's mod_rewrite stuff in .htaccess)
I tried changing $_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER'] to wp_get_original_referer() but it seemed to have no effect.
Incidentally, if I access my form page (at /free-reports/) as the first page on my site (after clearing cookies etc.) and printing $_SERVER['HTTP_REFERER'], it correctly shows the last offsite page - even though $_SESSION['offsite_referer'] doesn't.
I'm pretty perplexed, and have spent a fair amount of time trying to figure it out on my own, so any help to solve this would be appreciated.
Chances are, you can't really get the referer URL since some browsers don't send that and some people disable that, but here's how you could do that and I'll give you some extra tips here:
//first of all, initialize the session
session_start();
//Now call logvisit() to log where the user is coming from
logvisit();
function logvisit() {
$_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER']);
$browser = $_SERVER['HTTP_USER_AGENT']; //Gets the browser the user is using
//If you want to test it (disable the code below if you don't want to print that information):
echo "Offsite referer: $_SESSION['offsite_referer']<br>";
echo "Browser: $browser<br>";
}
Then to destroy the session you can use unset($_SESSION['offsite_referer']);
This is how I usually do it, and it's often a tidy way to do it.
I believe scunliffe had the key to this, as I was using IE to do the testing.
It works fine now, which I attribute to actually closing and restarting IE (apparently just deleting cookies doesn't do it, as you'd think, even though that works fine in Firefox).
I also changed what I was doing slightly to just save the full in-site browse history in a session variable, rather than only first and last page on the site.
The code I ended up with was the following, which is just at the top of my theme's header.php file:
<?php
session_start();
if (! isset($_SESSION['site_history'])) {
$_SESSION['offsite_referer'] = $_SERVER['HTTP_REFERER'];
$_SESSION['site_history'] = '';
}
$_SESSION['site_history'] .= ($_SERVER['REQUEST_URI'] . ';');
?>
I originally had session_start() also in wp-config.php when I was trying to figure this out, but was able to remove it (leaving just the above code in header.php) and things still work fine.
In case anyone finds this page wanting to do something similar, I was able to access this info in my WP page by adding the following to my theme's functions.php:
function get_offsite_referer() { return $_SESSION['offsite_referer']; }
add_shortcode('offsite-referer', 'get_offsite_referer');
function get_site_history() { return $_SESSION['site_history']; }
add_shortcode('site-history', 'get_site_history');
and then to pass the info on my Wordpress page/form:
<input type="hidden" name="offsite_referer" value="[offsite-referer]" />
<input type="hidden" name="site_history" value="[site-history]" />
scunliffe, if you'd posted your comment as a "reply" I would have "accepted" it, since it was what most closely led me in the right direction, but as a comment I could only upvote it so that's what I did. Thanks!

Unassigning a variables value from $_GET

I use;
$referrer = $_GET['_url'];
If I echo $referrer; it will display correctly.
If I use $referrer within a $_POST, it is empty. I think due to $referrer being assigned to $_GET.
How can I extract the value of $referrer into another variable so it is no longer assigned to the $_GET?
I hope that makes sense..
$_POST will only contain data IF you send that from form.
So, your code is basically right. Because you use referrer from within your URL.
If you really want to have $referer from $_POST, you will have to code something like this:
<form method="post" action="somewhere.php">
<input type="hidden" name="_url" value="{place the referrer here}" />
</form>
Or, like #Michael Gillette answer, you can change that with $_REQUEST.
hope that makes sense..
sorry, but it doesn't :)
$referrer become distinct variable with no relation to $_GET['_url']. It already contains value extracted from $_GET
there are not a single reason for $_GET sourced variables to conflict with $_POST.
Your problem is somewhere else.
It seems you're just trying to access variable that doesn't exist. Because every variable dies along with whole PHP after it's execution.
PHP scripts execution is atomic. It's not like a desktop application constantly running in your browser, and not even a demon with persistent connection to your desktop application. It's more like a command line utility - doing it's job and exits. It runs discrete:
a browser makes a call
PHP wakes up, creates an HTML page, sends it to the browser and dies
Browser renders that HTML and shows it to the user.
User clicks a link
a browser makes a call
another PHP instance, knowing nothing of the previous call, wakes up and so on
So, if you set your $referrer in one instance and trying to access it in another, it will fail. You have to re-sent it's value with next call
Use the clone keyword, as seen in the examples in this article:
http://php.net/manual/en/language.references.php
could you post an example of what you might like to do?
$referrer = $_REQUEST['_url'];
will return true on both GET and POST requests

Categories