$query = 'SELECT *
FROM ' . USERS_TABLE . '
WHERE user_id=' . $this->uid;
$sql = $db->sql_query ( $query );

$this->user_data = $db->sql_fetch_assoc ( $sql );

$this->lang_name = $this->user_data['user_language'];
$this->timezone = $this->user_data['user_timezone'];
$this->date_format = $this->user_data['user_dateformat'];
$this->user_theme = $this->user_data['user_theme'];

$this->load_user_settings();

The code above is found within a function within the user class. The variable $user_data is a public variable and is expecting an array.

The weirdness i'm finding which is bringing my work to a stand still is the following.

If I echo "$this->lang_name" it will display "en". Which is correct. However, if I echo $this->user_data['user_language'] it will not display anything. This is the same for the other variables.

So the below code will not work either. I've tried print_r and it does not display anything. I've removed my custom database functions and used the norm of mysql_query and mysql_fetch_assoc/mysql_fetch_array and it still does not work.

I've tried echoing $this->user_settings['fieldname'] and no value is being displayed.

I'm using PHP 5.2.9

public function load_user_settings()
	{
		global $db;

	$query = 'SELECT *
	FROM ' . USER_SETTINGS_TABLE . '
	WHERE user_id=' . $this->uid . '
	LIMIT 1';

	$sql = $db->sql_query( $query );

	$this->user_settings = $db->sql_fetch_assoc( $sql );
}

I've tried;

public $user_data;
public $user_settings;
public $user_data = array();
public $user_settings = array();

to no avail. Please help.

    My guess is that somewhere in the code you are overwriting the array with a scalar value, either within a class method or from within the code that instantiates the class. If it's a case of the latter (being overwritten from outside of the class), this is a good reason to make the array variable private and use setter/getter methods to control access to it.

    Then again I might be completely confused, since I don't know for sure what the code looks like and how/where the user_data variable is accessed.

      Also, to me it seems weird storing redundant data permanentely in the class

      class {
      	public function func() {
      		// This array holds all the data
      		$this->user_data = $db->sql_fetch_assoc ( $sql );
      
      	// And these variables hold the exact same data... again...
      	$this->lang_name = $this->user_data['user_language'];
      	// ...
      }
      }
      

      Why use both?

      // Either
      class exampleOne {
      	private $user_data;
      	// Remove all the others: lang_name etc
      
      public function load_user_setting() {
      	// ...
      	$this->user_data = $db->sql_fetch_assoc ( $sql );
      	// Check for validity of the array element values
      }
      public function get_user_lang() {
      	if (is_array($this->user_data))
      		return $this->user_data['user_language'];
      	else
      		// return false, throw error?
      }
      }
      
      // or
      class exampleTwo {
      	// Remove $user_data
      	private $lang_name;
      	private $timezone;
      
      public function load_user_setting() {
      	//...
      
      	// Limit scope for the array to local scope.
      	$user_data = mysql_fetch_assoc($resource);
      	$this->set_user_lang($user_data['user_language']);
      	// ...
      }
      private function set_user_lang($lang) {
      	// perform validation of $lang
      	$this->lang_name = $lang;
      }
      }
      
        NogDog;10927853 wrote:

        My guess is that somewhere in the code you are overwriting the array with a scalar value, either within a class method or from within the code that instantiates the class. If it's a case of the latter (being overwritten from outside of the class), this is a good reason to make the array variable private and use setter/getter methods to control access to it.

        Then again I might be completely confused, since I don't know for sure what the code looks like and how/where the user_data variable is accessed.

        Hi, I've used Dreamweaver to search the entire site and it doesn't return any results for user_data or user_settings apart from within the one file itself. Which does not unset any variables.

        Even if there was something removing the data from the variable, directly doing the following should result in it displaying the data no??

        Baring in mind I can successfully stick in an echo $this->lang_name and get its output.

        $query = 'SELECT *
        FROM ' . USERS_TABLE . '
        WHERE user_id=' . $this->uid;
        $sql = $db->sql_query ( $query );
        
        $this->user_data = $db->sql_fetch_assoc ( $sql );
        
        print_r ($this->user_data);
        
        $this->lang_name = $this->user_data['user_language'];
        $this->timezone = $this->user_data['user_timezone'];
        $this->date_format = $this->user_data['user_dateformat'];
        $this->user_theme = $this->user_data['user_theme'];
        
        $this->load_user_settings(); 

        johanafm

        I use the $this->lang_name etc as when a user is not logged in, it gets the default language, theme etc from the site configuration.

        i.e

        [code=php]if ( not_logged_in )
        {
        $this->theme = site->default;
        }
        else
        {
        $this->theme = user_data['theme'];
        }

          Are you saying that this exact code would display no value for the array key 'user_language', but would actually show a value for $this->lang_name? I'd claim that's impossible.

          $this->user_data = $db->sql_fetch_assoc ( $sql );
          
          print_r ($this->user_data);
          
          $this->lang_name = $this->user_data['user_language']; 
          echo $this->lang_name;

          Or are you leaving things out and that the effect might be that you for example have an error with the SQL query, resulting in the user being considered as not logged in and thus $this->lang_name is assigned the default value?

          saint4;10927873 wrote:

          I use the $this->lang_name etc as when a user is not logged in, it gets the default language, theme etc from the site configuration.

          Then I'd remove $user_data as a class member. I'm not saying you need to have your values in a specific place or that they must be of a specific type. I'm only saying that you should NOT store any value in multiple places since it's a recipe for disaster.

            Are you sure the function is actually ever executed? Are you sure the database queries are working and if so actually finding any data match? Have you enabled all error reporting (E_ALL)? Other than asking those questions, there's not much I can do other than speculate on hypothetical situations, since I don't have access to the entire class.

              That is exactly what I'm saying. I thought it was impossible too.

              I've hard coded the values within the sql statement too and used the default mysql_query functions instead of my own in case it was that but it wasn't.

              Can any of the PHP settings have this affect?

              $this->lang_name
              $this->timezone
              $this->date_format
              $this->user_theme

              The above is set regardless of the user being logged in or not otherwise there would be no text or a theme being displayed.

              $this->user_data is/was needed for when a user is logged in. Because I may need to retrieve other user data. I.e Name, DOB, address etc.

              Are you saying this is wrong?

                if ( $this->session_id == 0 )
                {
                  //default;
                }
                else
                {
                  // user data
                }
                

                The issue was the line of above.

                The $session_id variable contains a string of characters. Because I was comparing a string to an integer (I assume) it was returning true?? So it was actually displaying the default data and not the user data.

                I've rectified it by changing it to $this->session_id == '0' or I could have used ===

                  Yes, if you compare an integer to a string, the string will be cast to an integer. When cast to an integer, the result will be whatever digits are encountered at the start of the string until a non-digit character is reached; so "123abc" becomes 123, but "abc123" becomes 0. Boolean comparisons are different, though, as both of those strings would cast to boolean TRUE; so if you compared to FALSE instead of 0, you probably would have gotten the desired result. (0 is false, any non-zero number is true.)

                    Thanks. I've been coding for a few years now and never came across that before. Always learning something new.

                    Thanks for the information.

                      saint4;10927883 wrote:

                      Thanks. I've been coding for a few years now and never came across that before. Always learning something new.

                      Thanks for the information.

                      It's a somewhat subtle aspect of PHP that sneaks up on everyone at one point or another. It's worth spending a couple minutes taking a look at the Comparison With Various Types table on the linked manual page, as well as the Type-Juggling page. Or as you noted, using the "===" or "!==" identical operators can avoid the type-juggling, where that would be appropriate.

                        Write a Reply...