[nycphp-talk] Problem with $_SESSION, PHP 4.3.2, register_globals off, class methods
Phillip Powell
phillip.powell at adnet-sys.com
Sat May 1 16:38:11 EDT 2004
Very first lines of index.php:
[PHP]
session_start(); // USED FOR ANY STORED SESSION VARIABLES (ONLY
HAS TO BE SET HERE)
echo "PHPSESSID = $PHPSESSID<P>";
echo "SESSION the moment you first enter this script of $PHP_SELF is: ";
print_r(array_keys($_SESSION)); echo'<P>';
[/PHP]
This is what you see the moment you first go into index.php and have not
yet submitted a search query:
[QUOTE]
PHPSESSID = a964d0d6683757cafbe5576737ea5bf9
SESSION the moment you first enter this script of
/image_catalog/index.php is: Array ( [0] => search [1] => sql )
[/QUOTE]
Ok, now you submitted a search query. You entered some form stuff and
submitted. You're now at the search results page (which is also
"index.php"); this is what you see:
[QUOTE]
PHPSESSID = a964d0d6683757cafbe5576737ea5bf9
SESSION the moment you first enter this script of
/image_catalog/index.php is: Array ( [0] => search [1] => sql )
GET: Array ( )
POST: Array ( [0] => image_name [1] => allAlbums [2] => album [3] =>
boolword [4] => keywords [5] => persons [6] => events [7] => image_alt
[8] => image_creation_start_month [9] => image_creation_start_day [10]
=> image_creation_start_year [11] => image_creation_end_month [12] =>
image_creation_end_day [13] => image_creation_end_year [14] =>
image_location_city [15] => image_location_state [16] =>
image_location_country [17] => sortBy [18] => search [19] =>
isFromSearch [20] => section )
SESSION: Array ( [0] => search [1] => sql )
PHPSESSID = a964d0d6683757cafbe5576737ea5bf9
SESSION after setting it is: Array ( [0] => search [1] => sql [2] =>
hidden )
[/QUOTE]
(note: to save space and sensitive info I am not doing:
[PHP]print_r($_POST);[/PHP] but instead I'm using
[PHP]print_r(array_keys($_POST));[/PHP], and the same with $_GET)
$_SESSION['sql'] is set via an instance of SearchPerformer object that
runs the generateSearchSQL() method:
[PHP]
class SearchPerformer extends DBActionPerformer {
function SearchPerformer () { // CONSTRUCTOR
$this->doSearch(); // THIS METHOD RUNS generateSearchSQL()
}
function &displayResults() { // STATIC HTML STRING METHOD
$html = SearchView::retainFormElements($html); // SEE BELOW FOR
CODE DETAIL
// DO MORE STUFF TO $html
return $html;
}
function generateSearchSQL() { // SQL STRING METHOD
// BUILD $sql HERE WITH STUFF
$_SESSION['sql'] = $sql;
// DO MORE STUFF
return $sql;
}
}
$performer =& new SearchPerformer(); // CONSTRUCTOR
[/PHP]
So everything is fine so far; I have $_SESSION['sql'] and I even have
$_SESSION['hidden'] which is set via the displayResults() method in the
SearchPerformer object, it running this class method (class SearchView
is *NOT* instantiated here!!!):
[PHP]
class SearchView extends View {
function SearchView() {} // CONSTRUCTOR (you will be
instantiating SearchView objects elsewhere, just not in
SearchPerformer's methods)
function &retainFormElements(&$html) { // STATIC
HTML METHOD
print_r("<P>GET: "); print_r(array_keys($_GET));
print_r("<P>POST: "); print_r(array_keys($_POST));
print_r("<P>SESSION: "); print_r(array_keys($_SESSION)); print_r("<P>");
if ((!is_array($_POST) || @sizeof(array_values($_POST)) == 0) &&
$_SESSION['hidden']) {
$html .= $_SESSION['hidden'];
} else {
/*--------------------------------------------------------------------------------------------------------------------
Set $collection to either $_POST (if form post variables
exist in $_POST) or default to $_GET
to parse through either/or and produce HTML hidden elements
in either case
---------------------------------------------------------------------------------------------------------------------*/
$collection = ($_POST && is_array($_POST) &&
@sizeof(array_values($_POST)) > 0) ? $_POST : $_GET;
foreach ($collection as $key => $val) {
if (!is_array($val)) {
$hiddenHTMLRetainer .= "<input type=\"hidden\" name=\"$key\"
value=\"$val\">\n";
$html .= "<input type=\"hidden\" name=\"$key\"
value=\"$val\">\n"; // ADD FROM QS TO PASS BACK
} else {
foreach ($val as $innerKey => $indivVal) {
if ($indivVal) {
$hiddenHTMLRetainer .= "<input type=\"hidden\" name=\"${key}[";
$html .= "<input type=\"hidden\" name=\"${key}[";
if (!is_numeric($innerKey)) $html .= $innerKey; //
NUMERICAL KEYS DO NOT NEED TO BE PLACED INTO HTML ARRAY-FORMATTABLE FORM
ELEMENTS
if (!is_numeric($innerKey)) $hiddenHTMLRetainer .= $innerKey;
$html .= "]\" value=\"$indivVal\">\n"; // PUT IN
INDIVIDUAL ARRAY ELEMENTS
$hiddenHTMLRetainer .= "]\" value=\"$indivVal\">\n";
}
}
}
}
$_SESSION['hidden'] = $hiddenHTMLRetainer;
global $PHPSESSID;
print_r("PHPSESSID = "); print_r($PHPSESSID); print_r("<P>");
print_r('SESSION after setting it is: ');
print_r(array_keys($_SESSION));
}
return $html;
}
}
[/PHP]
Now, in the search results page I click a link to sort my results. The
link takes me back to, you guessed it, index.php (in fact, every single
portion of my application literally has only one address: "index.php"
and nowhere else). The moment I do that, this is what I see:
[QUOTE]
PHPSESSID = a964d0d6683757cafbe5576737ea5bf9
SESSION the moment you first enter this script of
/mu-spin/image_catalog/index.php is: Array ( [0] => search [1] => sql )
GET: Array ( [0] => section [1] => search [2] => isSort [3] => sortBy )
POST: Array ( )
SESSION: Array ( [0] => search [1] => sql )
PHPSESSID = a964d0d6683757cafbe5576737ea5bf9
SESSION after setting it is: Array ( [0] => search [1] => sql [2] =>
hidden )
[/QUOTE]
This is totally wrong!!! The $_SESSION['hidden'] variable is gone!!! It
is, in fact, erroneously RESET once again (with the wrong values),
whereas it was supposed to have been retained within $_SESSION
superglobal array, yet it is not.
I hope this makes it a bit more clear as to what is literally going on.
Synopsis:
1) I go to index.php
2) I see $_SESSION
3) I submit form elements
4) I see $_SESSION
5) I add $_SESSION['sql'] in generateSearchSQL() method
6) I add $_SESSION['hidden'] in SearchView::retainFormElements() method
7) I see $_SESSION with both elements
8) I click a link to go back to index.php
9) I see $_SESSION.. with just 'sql' and NOT 'hidden'
10) I tear my hair out, what little I have left!
Phil
--
---------------------------------------------------------------------------------
Phil Powell
Multimedia Programmer
ADNET Systems., Inc.
11260 Roger Bacon Drive Suite 403
Reston, VA 20191
#: (703) 709-7218 x107
Fax: (703) 709-7219
More information about the talk
mailing list