4

I have a class called "Layout" for the layout of the page, another class called "User" for the user.

Every page I create, I instantiate a new Layout.

When a user logs in, there is a new User instantiated.

How do I get an instance of the layout class to know about the instantiated user? I could also save the entire instance of the User in a session variable. I assume that's a bad idea though. What are the best practices for this?

class User
{
  var $userid;
  var $email;
  var $username;

  function User($user)
  {
     $this->userid = $this->getUid($user);
     $this->email = $this->getEmail($user);
     $this->username = $user;
  }
  function getUid($u)
  {
     ...
  }

  function getEmail($u)
  {
     ...
  }
}

class Layout
{

    var $var1;
    var $var2;
    var $var3;

    function Layout()
    {
        //defaults...
    } 


    function function1()
    {
        echo "something";
    }


   function function2()
   {
        echo "some other stuff";
   }

   function function3()
   {
      echo "something else";
   }

}

so in index.php, for example, i would do the following:

include "user.php"
include "layout.php"

$homelayout = new Layout();
$homelayout->function1();
$homelayout->function2();
$homelayout->function3();

now let's say that in login.php someone logged in:

include "layout.php"
include "user.php"

if(userAuthSuccess)
{
    $currentUser = new User($_POST['username']);
}

what is the best way to gain access to $currentUser and it's member variables such as $currentUser->email, etc. from all php files from here on out, as long as the user hasn't logged out?

5
  • $_SESSION doesn't support objects Commented May 26, 2010 at 3:12
  • You could pass the user instance as an argument to the layout constructor or as an argument to certain methods of the layout class... Commented May 26, 2010 at 3:28
  • $_SESSION supports objects just fine, as long before you start the session, you either load the objects' classes or define an __autoload function that can find and include them for you. Commented May 26, 2010 at 3:35
  • so which would be a best practice in this case? passing the instance of the user as an argument to the layout constructor, or just store the user object in a session? Commented May 26, 2010 at 3:39
  • can you show us some sample code so we know why you need this. seems like theres a better way. Commented May 26, 2010 at 5:19

5 Answers 5

1

I think the best remedy to the solution stated above is going for a concept called Dependency Injection, whereby you write an extra class, that will inject the dependency (An Object in this case) to the requesting class. Most of the modern developers will adhere to using this technique of injecting dependencies into their applications as this will enable:

Loosely coupled programs - As the dependency is injected by a third class, there is no need to hard code the dependency in the logic of the program.

Maintainable code - This is that feature of the OOP paradigm that allures the most. This is especially true when referring to large scale programs.

Memory Management - As a developer, you are free to manage the memory to your specification requirements.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry didn't realize that the topic is over 2 years old. Anyways could be useful to somebody else.
0

Since there will be only one User for every request and thus for every run of your program, this would be a case to make "User" a Singleton class as described here:

http://php.net/manual/en/language.oop5.patterns.php

That would provide the one way for other classes to refer to the current user without the chance of accessing the wrong instance since there is only one.

DISCLAIMER: Yes, I know that Singeltons are often used at the wrong places for the wrong purpose and some people tend to blame this problem on the pattern instead of the people who misused it for some smelly code. This however is a perfectly good use case for the Singelton pattern.

2 Comments

i have edited my post to show some code. let's assume i made the User class a singleton class...do I pass the instance of User to each of the other instances of the classes? If not, could you show some code to explain please.
If you User class is a singleton, you access it's only existing instance with User::singleton(), assuming the method names from the PHP manual page. That method will then always return the exact same instance of User and no other way of accessing it must be allowed.
0

"Globalizing" something by putting it in a session variable or cookie for the sole purpose of globalizing it is a very bad habit to get into, and it leads to tightly coupled libraries that rely on an arbitrary variable being set outside the class. Session variables in general are good to stay away from for other reasons, too.

The best way to get a variable into any class is to pass it as an argument. Do you have a method in your Layout class that renders (outputs) it? You may want to add a $data argument to that method that takes an associative array of data usable in the layout.

Comments

0

I'd personally use a registry class (Singleton) and register the user there for the Layout to access. That way, you only need to pass an instance of the registry to the Layout. The User class is not integral to the Layout's construction - since it should only be concerned with the Layout, so I wouldn't pass that in the constructor.

Another method would be to use a Controller to orchestrate these interactions between Views and Models. Whenever a new Controller is created, buffer it's output. Then, at render time, unbuffer the contents and assign them to properties (or a property array) of the view, which can then render them. You probably don't need an actual Model class to be passed to the View/Layout - just it's output.

Comments

0

Use a registry pattern. No need to make it a singleton, everyone is throwing that word around.

include "layout.php"
include "user.php"

if(userAuthSuccess)
{
    $data['currentUser'] = new User($_POST['username']);
}

$data['nav'] = new nav('home'); 

$homelayout = new Layout( $data );

Now $homelayout can access $data (which contains all the variables you put into it) via the data array.

5 Comments

in the case of a User class (where there is only 1 user per session), or a Database class (assuming there is only 1 connection necessary throughout), why would you suggest against a singleton class for both these cases?
whats the point? are you afraid you'll create more than one user on accident?
so to use your method, i would need to have a global variable to hold the status of whether the user is logged in or not, correct?
also, i would need to create a new User from every page
its one extra line of code. also makes it more readable for other people reading your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.