Jump to content

session variable error in query


684425

Recommended Posts

I am using the following code in PDO query

$this->query('SELECT * FROM users WHERE id = :id'); // line 11
$this->bind(':id', $_SESSION['users']['id']);       // line 12

it is working on local server, but on live server its giving some error or warning (i am not sure)

PHP Notice:  Undefined index: users in ... on line 12

but the query is still working correctly.

Please guide me what should i do to stop getting this error or warning or notice. Thanks🙂

Link to comment
Share on other sites

Not enough information. Where and how was the session variable set? Is there a session_start call at the beginning of this script?

There may be other issues, unrelated, with your query as well. You are not using prepared statements which may be OK as long as ':id' is not coming from a web page. Also it is bad practice to use * in a query. Specify only those columns you intend to actually use.

  • Like 1
Link to comment
Share on other sites

On 7/16/2020 at 6:23 PM, gw1500se said:

Is there a session_start call at the beginning of this script?

Yes, it is called on top of everything.

<?php
// Start Session
session_start();

// Include Config
require('config.php'); // db config

require('classes/Messages.php'); // error or success messages
require('classes/Bootstrap.php'); // handling controllers, actions and requests according to URLs
require('classes/Controller.php'); // handling includes
require('classes/Model.php');  // *this one contains functions related to queries.

require('controllers/home.php');
require('controllers/shares.php');
require('controllers/users.php'); // in this file the session variable was set, when user submits username (no password is required) 
                                  // Using * in query is for testing purpose only
require('models/home.php');
require('models/share.php');
require('models/user.php');

$bootstrap = new Bootstrap($_GET);
$controller = $bootstrap->createController();
if($controller){
	$controller->executeAction();
}

Below is the code from model.php

<?php
abstract class Model{
	protected $dbh;
	protected $stmt;

	public function __construct(){
		$this->dbh = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);
	}

	public function query($query){
		$this->stmt = $this->dbh->prepare($query);
	}

	//Binds the prep statement
	public function bind($param, $value, $type = null){
 		if (is_null($type)) {
  			switch (true) {
    			case is_int($value):
      				$type = PDO::PARAM_INT;
      				break;
    			case is_bool($value):
      				$type = PDO::PARAM_BOOL;
      				break;
    			case is_null($value):
      				$type = PDO::PARAM_NULL;
      				break;
    				default:
      				$type = PDO::PARAM_STR;
  			}
		}
		$this->stmt->bindValue($param, $value, $type);
	}

	public function execute(){
		$this->stmt->execute();
	}

	public function resultSet(){
		$this->execute();
		return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
	}

	public function lastInsertId(){
		return $this->dbh->lastInsertId();
	}

	public function single(){
		$this->execute();
		return $this->stmt->fetch(PDO::FETCH_ASSOC);
	}
}

One more thing that session variable was giving multiple errors on live server when I used it from mobile. i handled most of them using isset() but i don't know how to handle the one that i mentioned in my first post. Please guide.

Link to comment
Share on other sites

5 hours ago, gw1500se said:

I don't see where that variable is set anywhere.

public function verify(){
		// Sanitize POST
		$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

		if($post['submit']){
			// Compare
			$this->query('SELECT * FROM users WHERE username = :user');
			$this->bind(':user', $post['username']);
			$row = $this->single();
			if($row){
				$_SESSION['isusers'] = true;
				$_SESSION['users'] = array(
					"id"	=> $row['id'],
					"name"	=> $row['name']
				);
				header('Location: '.ROOT_URL.'messages');
			} else {
				Messages::setMsg('Incorrect username', 'error');
			}
		}
		return;
	}

Now after this, when session variable was called on any other page. it was throwing error. Most of which i handled using isset() but in the situation mentioned in my first post i don't know what to do.

Link to comment
Share on other sites

7 minutes ago, gw1500se said:

What does 'single' do and return?

it extracts a single row from the database (i have pasted the whole class named model in model.php in my previous post and the below function is in the last of that class)

public function single(){
	$this->execute();
	return $this->stmt->fetch(PDO::FETCH_ASSOC);
}

 

Link to comment
Share on other sites

5 hours ago, gw1500se said:

I think fetch returns false only on failure. A query can be successful but return no rows. You might want to check to that condition.

 

I did check it and each of the queries are working as they should. Everything else is perfect even session values are set and working on every page. but still i am getting this session index notice that it is not defined.

Link to comment
Share on other sites

the error you are getting is a follow-on error, due to code being executed when a 'required' input is not present. if you have a section of code that requires a logged in user, your code should test if the session variable isset() before ever executing that code. this will stop the follow-on error.

the actual problem is a session variable that should be set but isn't. in the first post and your post above, you have stated/implied that the SELECT query in the first post is being executed/working. how do you know it's working. what code is using the result from that query and what result or output are you getting that leads you to believe that particular query/section of code is working?

taken by itself, a symptom of code that seems to work and also produces an error is usually a sign that the code is being executed twice, once with and once without the expected input data.

next, there's a bunch of issues with the rest of the code you have posted -

  1. you should have an auto-loader to load the class definitions. also, 'require' isn't a function and the () around the filenames are not needed.
  2. the responsibility and most of the code in model.php is not needed. if you want to do something useful for a database class, extend the PDO class with a general-purpose prepared/non-prepared query method that accepts a second optional array of input parameters and prepares/executes the query if there are input parameters and just calls the PDO query() method if there are no input parameters.
  3. your main code should be responsible for making a database connection, since it knows if, how many, and where those connections should be used, then use dependency injection to supply the connection to any class that needs it.
  4. you should not use defined constants for the database connection credentials. this limits the code to using only a single database connection.
  5. you should use exceptions for database statement errors and in most cases let php catch and handle the exception, where php will its error related settings to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) the exception to this rule is when inserting/updating user submitted data and a duplicate or out of range error can occur. in this case, your code should catch the exception, test if the error number is for something that your code is designed to handle, setup and display a message for the user telling them what was wrong with the data that they submitted. for all other error numbers, just re-throw the exception and let php handle it.
  6. you should set emulated prepared queries to false, you want to run real prepared queries, and set the default fetch most to assoc, so that you don't need to specify it in each fetch statement.
  7. by having a 'query' method that is actually preparing the query, you have created confusion and more work for anyone who will have to read/maintain this code.
  8. if you simply supply an array of the input data to the execute([...]) call, you don't need any of the code for binding inputs. also, by using bindValue(), you cannot directly execute the same query again with different data and is_int() in that code isn't doing anything for integer values that are in a string variable type.
  9. the verify() method also has responsibility and code issues. just some of them - the only user data you should store in the login session variable is the user id (auto-increment primary index.) you should query on each page request to get any other user related data/permissions. this is so that any change in the user data/permissions will take effect on the very next page request, without requiring the user to log in again. also, all header() redirects need an exit/die statement after them to stop code execution.
  • Like 1
Link to comment
Share on other sites

21 hours ago, mac_gyver said:

the error you are getting is a follow-on error, due to...

Thank you Sir for this detailed answer and your advice. I had a doubt that i was going wrong somewhere in this project but each of your word is telling me that i should study php more because there is a bunch mistakes in my code (but i am really surprised that the code is still working as expected. Sorry about repeating this again)

(i am not a proper literate in programming because computer science or programming was not my subject in school and i was unable to continue my studies due to more than ten years of unemployment. its just that i am crazy about learning it. your reply has told me that i am not ready yet for working as a programmer, even for my own experiments like this one. programming is not my profession, it is my craze)

Thanks to all of the experts on this forum for guiding me and others too. i am sure that your guidance will improve my knowledge 🙂

Link to comment
Share on other sites

22 hours ago, mac_gyver said:

you have stated/implied that the SELECT query in the first post is being executed/working. how do you know it's working

i forgot to answer this.

Most of the queries in the project execute at the time of page load and these pages display expected data accurately that comes from the database. The session variable error that i am getting is coming from one page only but that page too is displaying exactly the same data which is stored in database.

PS: Right after my previous reply, I did wrap my code in a condition to confirm that the session variable is set or not and used a redirect if it is not set. Php redirected me to the other page and told that the variable is not set. The other mistake that i have found is that i was setting one session variable with same name twice on two different pages. (First page is storing an array of lets say three elements ABC in a session variable and the other page is storing an array of "Those three elements" ABC "again with three more elements" DEF in the same session variable)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.