Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

_SESSION variables in a loop in a form 2

Status
Not open for further replies.

svar

Programmer
Aug 12, 2001
349
GR
Consider this (after a query):
Code:
    while($row = mysqli_fetch_array($result,MYSQLI_NUM)):
$html='<html>
<body>
<table width="100%" border="1">
  <tr>
    <th>$row[1]</th>
    <th>$row[2]</th>
    <th>$row[4]</th>
    <th>$row[5]</th>
    <th>$row[6]</th>
    <th>HREF="dosomething.php" Do something with row[6]</th> ';
echo $html;
endwhile;

Basically this produces a table and for each table entry, the user may click and select to do something for that entry ($row). So somehow I need to pass the $row to the dosomething form.
One way we discussed is
Code:
$_SESSION["row"]=$row
, but this assumes that at the time the user clicks the $_SESSION[row] is the current row, rather than the last row produced by the query.
A similar way might be
Code:
 <th>HREF="dosomething.php?variable=$row[6]" Do something with row[6]</th> ';

I am not sure this will work, since the table appears first, before the user decides to click.
So I am curious how would one do that, i.e. "package" the row with the form called.
 
I don't think it is a good idea to have multiple <html> and <body> tags in the same document. Nor multiple table tags in the same table (at least, not without closing tags)

remember - php is stateless. so you MUST provide the user with a way of telling the server with what he wishes to interact. the normal way to do this is to encode some data into the url (as you are suggesting) or use hidden form fields. You could complicate this and use sessions too, but I'm not sure it is advisable in this type of context.

so in a typical environment, your 'row' would have a unique id associated with it (perhaps an autoincrementing primary key in $row[0] ?) and you would encode this in the link.

Code:
<?php
..do query
?>
<html>
<body>
<table width="100%" border="1">
<?php 
while($row = mysqli_fetch_array($result,MYSQLI_NUM)):
?>
  <tr>
    <th><?php echo htmlspecialchars($row[1]);?></th>
    <th><?php echo htmlspecialchars($row[2]);?></th>
    <th><?php echo htmlspecialchars($row[3]);?></th>
    <th><?php echo htmlspecialchars($row[4]);?></th>
    <th><?php echo htmlspecialchars($row[5]);?></th>
    <th><?php echo htmlspecialchars($row[6]);?></th>
    <th><a href="dosomething.php?action=editRecord&recordID=<?php echo $row[0];?>">Edit</a></th>
  </tr>
<?php endwhile;?>
</table>
</body>
</html>
 
Thanks, this is helpful

First, on a side note: If I understand you correctly you prefer jumping between PHP and html rather than
using something like
Code:
$toecho='...html stuff ...';
echo $toecho;
Is there a reason for this? It looks preferable to me since I avoid too many jumps and seems easier for me to read the code(except that I missed the closing tags as you point out when pasting the code).


Now to the main point:

1)
Code:
?php echo htmlspecialchars
I guess santizes stuff to avoid sql injections, though $row came from a query to the db. Not sure if there is more to it.

2)
Code:
<a href="dosomething.php?action=editRecord&recordID=<?php echo $row[0];?>">Edit</a></th>
  </tr>
Actually the unique identifier may be a combination of fields, e.g. $row[0].$row[1].$row[2]
but I could have a loop counter. So in such a case I need something like
Code:
<a href="dosomething.php?varname1=<?php echo $row[0] ?>&varname2="><?php echo $row[1] ?>&varname3=<?php echo $row[2] ?>dosomething with that row</a>
Then in dosomething.php I need
Code:
$var1 = $_GET['varname1'];
$var2 = $_GET['varname2'];
$var3 = $_GET['varname3'];
Am I missing something here?
 
'prefer' is too strong a word. In templating scenarios I prefer using that method as I can check the template easily in the browser within my IDE. In other scenarios I would use heredoc, but I did not want to complicate the answer too much. For echo'd inline information I would break out from quotes.

I guess santizes stuff to avoid sql injections

nope. imagine that the data field might be commenting on html and contain something like: "The framework of every web page is a doctype and some standard tags like this:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
..."
if you echo'd that straight out then the browser would not understand that it is supposed to print those exact characters rather than interpret the characters as part of a tag. So you need to convert the braces to html entities.

Actually the unique identifier may be a combination of fields, e.g. $row[0].$row[1].$row[2]
but I could have a loop counter. So in such a case I need something like
so long as you have sufficient information to identify the record uniquely anything will do.

 
It seems that the $_SESSION["..."] may get lost after redirects(i.e the initial php form where the variable is defined calls another which however 'forgets' it. I checked that there is no other session_start except at the very first form. Could this be a configuration error, e.g. php.ini?
 
it should not get lost because the redirect should also send the session cookie. What you may be seeing is a race condition where the session store on the server is not being fully saved before the session is restarted on the new (redirected) page request.

This can be avoided/mitigated by expressly calling
Code:
session_write_close();
before you output the header redirect.
 
I must still be doing something wrong, could it be because I use echo instead of jumping out of php to html an back?
Code:
...
}else if ($condition1){
session_write_close();
$href2='<td width="30%"> <A class=lightblue HREF="menu.php"> click on link to proceed</A> </td>';
echo "$href2";
}
 
depends what the 'something wrong' might be. are you getting active error messages? if so what are they? Remember to check in your php logs as well as check the screen (assuming you have error reporting and error display turned on in php.ini

note that there is no need to enquote variables
Code:
echo $href2; //not echo "$href2";

some things server side to watch out for:

1. check the session store location in php.ini and make sure it exists and is writable/readable by whatever user under whose credentials php runs.

2. check that the browser you are testing with allows session cookies. if you are likely to run into a non-session-cookie problem again and again, it may be worth coding for trans_sid based session authentication as a backup. (session.use_trans_sid). if you go the trans_sid route for security purposes you should check the session id against a captured IP address to stop session-hijack attack vectors.

3. check php.ini generally for the runtime configurations here: and make sure that they all make sense to your setup
 
Also are you sure you are calling session_start() in your menu.php file to initiate the session there?

Otherwise the session is not available, and $_SESSION will be undefined.

Also make sure you have display_errors set to on in your PHP.ini and error_reporting set to E_ALL so you get errors displayed if you aren't getting any.

----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.

Web & Tech
 
Also are you sure you are calling session_start() in your menu.php file to initiate the session there?
Otherwise the session is not available, and $_SESSION will be undefined.
If that's the case, then this is probably the problem.
It was not clear to me based on
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.

So, if I have the following

initial.php // has a session_start() and sets superglobals $_SESSION["var1"] and $_SESSION["var2"]
calls menu1.php or menu2.pho (no arguments, just a selection menu and needs no session_start
menu1.php calls menu11.php which needs $_SESSION["var1"]
menu11.php calls menu111.php which also needs $_SESSION["var1"]

so both menu11.php and menu111.php need a session_start() to resume the session and retrieve $_SESSION{"var1"}
but menu1.php does not. Is that correct?
 
Session start must be called for each script. Not each file.

So if a file is required or included it does not need a separate call to session_start

At the end of a script the session store is saved and closed. This essentially means that the session superglobal is serialised and stored in a text file.

So when the script starts you need to fell php expressly to look for the session cookie and open the session store or create a new one.

When you call session start a cookie is sent to the browser. So the call just be made before you output any text to the browser (just like and header). Text includes white space for this purpose.
 
Session start must be called for each script. Not each file.

So if a file is required or included it does not need a separate call to session_start

At the end of a script the session store is saved and closed. This essentially means that the session superglobal is serialised and stored in a text file.

So when the script starts you need to fell php expressly to look for the session cookie and open the session store or create a new one.

When you call session start a cookie is sent to the browser. So the call just be made before you output any text to the browser (just like and header). Text includes white space for this purpose.
 
vacunita wrote:
Also are you sure you are calling session_start() in your menu.php file to initiate the session there?

Otherwise the session is not available, and $_SESSION will be undefined.
jpadie wrote:
Session start must be called for each script. Not each file.
So if a file is required or included it does not need a separate call to session_start
while the docs speak of resuming the current session.

So I am confused.

My understanding of require/include is that it effectively adds a piece of code, namely the required/included php file
in place of the require/include statement. But if one is going to actually use a separete php file, one does not necessarily need to require/include it, e.g. a php file inside an href.
In my example, there is no require/include; initial.php may call menu1 via an href or form action. So I am confused.
superglobals $_SESSION defined in initial.php are apparently not known by the menu1.php and children called via hrefs or forms. All these files are ONE script if I understand correctly, so if I understand jpadie session_start() in menu1.php and children is not needed(but when I test the superglobal at the start of menu1 it's empty), while if I understand vacunita, they are needed?
 
You're getting confused between state and stateless.

Outputting a link that refers to a php file is completely irrelevant to the server. It is information that is useful only to the browser. And there is no active link between a browser and a php server that maintains state.

If the user clicks on a link in a browser there is a new get request to the webserver which in turn instantiates a new phone script. Each new script (or new page request/refresh) requires a session_start command if you are going to use sessions. You could also auto start the session via php.ini.

Included/required files form part of the same script that includes or requires them. They are simply a method of neatly reusing groups of functions or classes whilst keeping them logically arranged in their own 'compartments'. They might as well all be included in the same big file from php's perspective.

If you wish to hedge your bets either use session auto start or include this code at the top of all your physical files.
Code:
if(session_id()=='')session_start();
 
What jpadie means is that every time you call a PHP script (not a file) you need to call session_start() to use the SESSION variable.

Imagine you have 2 doors. you get a piece of paper from Door #1 that tells you to do certain things. When you are done you are told to hand your result to whoever is behind Door #2.

Door #2 takes your work and does other things, and maybe hands you something back.

Your are the browser. Whatever is behind the doors are your PHP scripts. Door #2 has no idea of what Door #1 did. Only what you hand it back. Now imagine a Session as a a folder of things that Door 1 stores in a file cabinet Door 2 can access. Door 2 based on a session ID that Door 1 stores with you, pulls the appropriate folder from the file cabinet (it could have many folders from Door 1). And has access to that information plus whatever you hand it back.

This is called statelessness. When Door 1 finishes what it is doing, it cleans everything, so all information and data not stored is lost. Door 2 starts its job from a clean plate. No data unless it gets it from what you hand it, or what is stored in a folder (session) it can access.

You have no idea as the browser what happens behind either of the Doors you just get back results. And an identifier for the folder that belongs to your process. i.e your Session.
















----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.

Web & Tech
 
Good example. So doors 1 and 2 are two php FILES, e.g. menu1.php.
Door 2 having access to Door's1 SESSION cabinet means they are on the same directory?
Also,
When Door 1 finishes what it is doing, it cleans everything, so all information and data not stored is lost
when does Door1 "finish what it is doing"? When the page is no longer displayed? I guess not, unless you exclude the cabinet.
When does Door1 clean up its SESSION cabinet? When the hyperlink is closed?

With regard to storing, these cabinet $_SESSION info may be stored either in memory on the server or on some temporary (cookie-like) file. Which of the two methods does php use?
 
A php script finishes when the last line of code is executed. This could be long before the page is displayed on the browser.

Typically session data is stored in a folder that is accessible to the webserver but not in the web root (for security). So door2 and door1 both have access to the same folder.

But door 2 does not know how to choose which file is the session store for your browser. You need to give it the bit of paper that you got from door 1. The bit of paper has your unique Id written on it which allows door 2 to go find your drawer and retrieve all your session data. Without this bit of paper you are unknown to the server.
 
Door1 finishes what its doing when it hands you whatever it did and closes the door. In other words when it hands the browser the results of the PHP script. When the Browser displays the page PHP has stopped running and as such the script has finished executing.

PHP:
      PHP Runs here
 |
[server]    
 |
[browser]

[quote]
Door 2 having access to Door1's SESSION cabinet means they are on the same directory?
[/quote]

Not necessarily.   Door 2 can be in a directory that is completely separate of Door 1 and still is able to go and retrieve the session that Door 1 saved. For instance: /webroot/scripts/door1.php  and /webroot/otherfolder/assets/scripts/door2.php  

Location of the files is irrelevant to sessions. As they are stored by PHP in a directory not related to where the php scripts are. This session directory is usually set in the PHP configurations in php.ini

Typically Sessions are cleared when the Browsers closes yes. The session ID stored in your browser is removed. Though you can set different session timeouts and maxlifetime directives again in the php.ini.  file.


Sessions are typically stored in files. Though they can also be stored in a database if configured as such. 

----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown. 

[url=http://behindtheweb.blogspot.com/] Web & Tech [/url]
 
Thanks again to both. I am still confused, albeit less

1) Unless I misunderstood something, script=the set of the initial file/link (e.g initial.php) plus all php files and children thereof called by the initial file accessed by the browser.

If so, how do these 'know' they belong to the same 'script', so that cabinet/SESSION info is accessible by the different files/doors but not by other files/foors that belong to a diffrent 'script'? From jpadie's answer I assume that ALL session info (SESSION info for ALL scripts currently running and not cleared) is stored somewhere in the server and it's the piece of paper the browser gives that tells the server which SESSION info to pick. Kind of like going to a bank (the server folder) with an account number (the paper by the browser identifying his session). Is that close ?

Door1 finishes what its doing when it hands you whatever it did and closes the door. In other words when it hands the browser the results of the PHP script. When the Browser displays the page PHP has stopped running and as such the script has finished executing.

PHP:
 PHP Runs here
|
[server] 
|
[browser][/quote]

Door 1, which is a php file does a query, displays some dynamically generated html and offers you a choice of hyperlinks. You click on one of them and get php file Door2. Door 1 has closed, but $_SESSION vaiables generated by Door1 is not erased and the script (in the sense I understand it) has not finished running. Or does script refer to each php file?
 
1.
script=the set of the initial file/link (e.g initial.php) plus all php files and children thereof called by the initial file accessed by the browser.
correct. within the terminology that we are employing here.

2.
how do these 'know' they belong to the same 'script'
there is no imputed knowledge. if a file is 'included' into a script then it is as if the code within that file were in the calling code. i.e. the physical location of the file is irrelevant. that particular 'thread' (term used very loosely) of php that is running the script has access to the session data.

3.
Kind of like going to a bank (the server folder) with an account number
correct. but don't take the analogy too far. go look in your session directory - you will/should see hundreds (if not more, depending on the busyness of your site) of text files with long names. each name corresponds to a session id, which is stored in the session cookie that is sent and stored by the browser. It is as simple as that. the server receives the cookie, gets told to start the session, looks up the cookie value, checks to see whether a file exists in the session-store, read the file, unserialises the data in the file and stores the unserialised data in $_SESSION.

this code is equivalent
Code:
$fileName = '/path/to/session/dir/' . $_COOKIE[session_name()];
$fh = fopen($fileName, 'r');
$content = fread($fh);
$_SESSION = unserialize($content);

4.
$_SESSION vaiables generated by Door1 is not erased
it is no longer available in $_SESSION. however the php session manager will serialise the data and store it in the session file. this code is equivalent
Code:
$string = serialize($_SESSION);
$fh = fopen('/path/to/session/dir/' . session_id(), 'w');
fwrite($fh, $string);
fclose($fh);

5.
has not finished running
the script finishes running when the last line of the script is processed. it does not wait on the browser in any sense.

6.
Or does script refer to each php file?
within the terminology we are using here, no. A script may equate to a single php file, but there is no need for it do so.

a far wiser head than mine wrote this FAQ a long while back; it holds true today. It's worth a read.
faq434-4908

it is also well worth reading the manual on sessions:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top