Link to home
Start Free TrialLog in
Avatar of doctorbill
doctorbillFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Using PHP session variables

<?php


if(!empty($_FILES)){
    
    //database configuration
    $company = $_GET['company'];
    $dbHost = 'localhost';
    $dbUsername = 'root';
    $dbPassword = 'billadmin2006';
    $dbName = 'inventas';
    //connect with the database
    $conn = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);
    if($mysqli->connect_errno){
        echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
    }
    
    $targetDir = "uploads/";
    $fileName = $_FILES['file']['name'];
    $fileSize = $_FILES['file']['size'];
    $targetFile = $targetDir.$fileName;
    
    if(move_uploaded_file($_FILES['file']['tmp_name'],$targetFile)){
        //insert file information into db table
        $conn->query("INSERT INTO documents (companyName, f_name, d_date, f_size) VALUES('".$company."','".$fileName."','".date("Y-m-d H:i:s")."','".$fileSize."')");
    }
    
}
?>

Open in new window


The $company = $_GET['company']; is just not getting added to my database. The url is fine - the GET value is correct. If I set the $company = 'test'; it works. I am only using GET to test - I would usually use POST
Could I use a session variable - if so how do I set a session variable that can be used in multiple pages as a variable for database input
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

If you're not POSTing your form, then you won't get any $_FILES, and if you are POSTing your form, then the only way $_GET['company'] will exist is if the URL you're POSTing to includes a querystring : somepage.php?company=someValue.

I would suggest you turn on error_reporting, and var_dump the $_POST and $_GET arrays, just so you can see what your script is receiving:

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);
var_dump($_POST);
var_dump($_GET);
var_dump($_FILES);

if(!empty($_FILES)){
    ...

Open in new window

The fact that you're inserting to your DB from user input, you really should be using a prepared query for security reasons.
Avatar of doctorbill

ASKER

Having reviewed my form I think the way forward is for me to use sessions but I am not sure how to use them across multiple pages
To use sessions in PHP is pretty straight forward. Firstly, you need to start the session (whether you're reading or writing to it) Add this to the top of your scripts:

<?php
session_start();

Then you just use the $_SESSION array like any other:

// set a session variable
$_SESSION['someKey'] = "Some Value";

// read a session variable:
echo $_SESSION['someKey'];

Others functions exists to help you manage the session such as session_destroy() etc.
Do I need to use session_start on the other pages that use the session variable and echo the variable:
If so how do I use it as a variable to enter into a database

Or do I need to define a variable name:
$name = $_SESSION['somekey'];
Then enter $name as a database input variable
Yeah ... any time you want to use the session variables, you need to call session_start(). Once you've called that you can access the session variable just like any other variable.

You can enter the variables straight into the DB if you want - either directly or using a prepared query (preferred method):

$db->query( "INSERT INTO myTable (someColumn) VALUES ({$_SESSION['someKey']})" );

or

$stmt = $db->prepare( "INSERT INTO myTable (someColumn) VALUES (:name)" );
$stmt->execute(['name' => $_SESSION['someKey']);

Or you can assign the session variables to your own variables. Makes sense to do that if you need that they exists:

$name = isset($_SESSION['someKey']) ? $_SESSION['someKey'] : null;
Thanks so much - Will try this and report back
JUst 2c comment on session_start:
- 'any time you want to use the session variables' more precisely you need it once on every page where you will be using session variables,
- I personally use session_start on every page, just to be sure. BUT I close the session just after the start, with session_write_close, unless I have to update session variables values. In which cas I close the session just after the write.
See http://php.net/manual/en/function.session-write-close.php
This is the code I am attempting to use
The session variable is  being seen by the echo command on the page but still not being entered into the database:
The "someKey" value is being seen on the page
I am trying to enter the value into the companyName field in the insert statement
I have a feeling I am not understanding this part: "query("INSERT INTO files......"

<?php

session_start();
echo $_SESSION['someKey'];

if(!empty($_FILES)){
   
    //database configuration
    $dbHost = 'localhost';
    $dbUsername = 'root';
    $dbPassword = 'xxxxxxxxxx';
    $dbName = 'inventas';
    //connect with the database
    $conn = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);
    if($mysqli->connect_errno){
        echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
    }
   
    $targetDir = "uploads/";
    $name = $_SESSION['someKey'];
    $fileName = $_FILES['file']['name'];
    $fileSize = $_FILES['file']['size'];
    $targetFile = $targetDir.$fileName;
   
    if(move_uploaded_file($_FILES['file']['tmp_name'],$targetFile)){
        //insert file information into db table
        $conn->query("INSERT INTO files (companyName, file_name, uploaded, file_size) VALUES('".$name."','".$fileName."','".date("Y-m-d H:i:s")."','".$fileSize."')");
    }
   
}
?>
ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I will change the session name when tests work - I know it not a good name at the moment
If I access the page I get the following echo result:
sessiontestvalue
This is correct
Yes - the other data is entered into the database correctly but the companyName field is left blank
The bit I am confused about is that the data should be entered into a table called documents. It looks as if it is entering into files
Now working- I just realised I was looking at the incorrect upload file. Your solution has solved the issue
OK. That will be down to your SQL statement:

INSERT INTO files ...

I'm guessing that should probably be:

INSERT INTO documents ...

What happened when you var_dumped the data. That will show you exactly what SQL you're trying to run against the DB and immediately identify any problems.

Were all the values correctly filled in. Are you sure your table has the correct columns (companyName, file_name, uploaded, file_size) and that the datadatype is suitable for the values (text / number / date etc). Is ther any chance your companyName contains any odd characters (quotes / slashes etc.)

Once you've got this working i would STRONGLY recommend that you start using prepared statements for the INSERT.
OK. Good news :)
Thanks very much for your help and advice on this. I will certainly take it on board
Beware that the code posted by Chris in  #a42656407 will NOT work  as expected if there was a change in $_SESSION[] value.
Unless thare has been a session_write_close between "$_SESSION[]='xxxx'" and "print $_SESSION[]"
This is really counterintuitive, and might lead to very difficult debugging... unless you know the trick of course
Hmmmm.

Not sure what you're referring to Bernard. Maybe you can clarify ...

This works fine:

session_start();
$_SESSION['someKey'] = "Some Value";
echo $_SESSION['someKey'];

Open in new window

(I did not used this in php 5.6 or 7.x, so my findings might be deprecated)
See http://php.net/manual/en/function.session-write-close.php#112681

Lucky you, you did not meet this debugging nightmare!
That does not mean however that you or others will never stumble over it!

On several occasions, a program of mine like this one  was not working as expected: the new value was not available in $_SESSION until the page was closed or (I discovered later) a session_write_close had been issued...
your mileage may vary with php versions or underlying server...
but any time I change $_SESSION values that I might need later in the page... I consider doing a write_close.

Of course, even though you "write_close" the session, its read access is not closed and you can still read it.
As a routine, in fact I personally issue a session_write_close just after the session_start, thus making life easier for php and the Apache server.
B-) and if I forget this close while issuing later a change to SESSION, the error message is clear and I instantly know what i need to do: usually commenting out the write_close and placing it further down in the code

If you want to make your code robust and predictable against any changes in server or php versions, do consider using session_write_close!!

Important Reminders:
- session_start must be issued before any html has been sent by the server, so it is usually more robust to pl ce it in the very fist lines of code, most notably before any include (which if not following good practices might send spaces which will then be considered as html)
- you can issue a new session_start after a session_xrite_close, but this still needs to happen before any html is sent
- session_write_close may happen anywhere you want in your code
Hey Bernard,

Thanks for the clarification.

However, I think the problem your referring to is more to do with concurrent / asynchronous calls to the session - if you're just setting a session variable and reading it back in on the same page, then there's nothing to worry about. Where a problem can arise is if you're trying to access the session across several scripts at the same time (AJAX / iFrames etc). On session_start, PHP locks the session, reads in it, and then writes it back out when execution finishes, releasing the lock in the process.

Now if you try to read the session in again during the execution of the start / lock / read / write/ unlock, then you'll get a race condition as the session will be locked.

Calling session_write_close() will effectively flush the session data to disk and release the lock, preventing the sharing conflict - but ... it's edge case.

I can't comment on why you had problems with your session, but for a simple start / write / read, there's absolutely no need to flush the session.

Having said all that ... I can't really think of a good reason why anyone would want to set a session variable and read it back in the same page - you'd clearly have the value that you set, so just use that instead :)
- the cases where I failed on this problem were not async or similar

- maybe the behaviour is different if sessions are stored in files or in a db

- there are occasions where you do some computation, want to store the result in a session variable, then proceed computing (so the previous variable content is changed) and make some comparision with the earlier version....