Asked  7 Months ago    Answers:  5   Viewed   38 times

Possible Duplicate:
Who needs singletons?

I always write with respect to best practice, but I also want to understand why a given thing is a best practice.

I've read on in an article (I unfortunately don't remember) that singleton classes are prefered to be instantiated, rather than being made with static functions and accessed with the scope resolution operator (::). So if I have a class that contains all my tools to validate, in short:

class validate {
    private function __construct(){}
    public static function email($input){
        return true;
    }
}

I've been told this is considered bad practice (or at least warned against), because of such things as the garbage collector and maintenance. So what the critiques of the "singleton class as static methods" wants, is that I instantiate a class I'm 100% certain I will only ever instantiate once. To me it seems like doing "double work", because it's all ready there. What am I missing?

What's the view on the matter? Of course it's not a life and death issue, but one might as well do a thing the right way, if the option is there :)

 Answers

78

An example singleton classes in php:
Creating the Singleton design pattern in PHP5 : Ans 1 :
Creating the Singleton design pattern in PHP5 : Ans 2 :

Singleton is considered "bad practice".

Mainly because of this: How is testing the registry pattern or singleton hard in PHP?

  • why are singleton bad?

  • why singletons are evil?

  • A good approach: Dependency Injection

  • Presentation on reusability: Decouple your PHP code for reusability

  • Do you need a dependency injection container

  • Static methods vs singletons choose neither

  • The Clean Code Talks - "Global State and Singletons"

  • Inversion of Control Containers and the Dependency Injection pattern

Wanna read more? :

  • What are the disadvantages of using a PHP database class as a singleton?

  • Database abstraction class design using PHP PDO

  • Would singleton be a good design pattern for a microblogging site?

  • Modifying a class to encapsulate instead of inherit

  • How to access an object from another class?

  • Testing Code That Uses Singletons

A Singleton decision diagram (source):

Singleton Decision Diagram

Wednesday, March 31, 2021
 
lena
answered 7 Months ago
70

While you can hash a user_id and secret_key, anyone who intercepts this cookie can log in to your application. In addition to this, you can make it so that your remember me cookies go stale very quickly. No one likes a stale cookie.

You can store the time stamp of each user's last visit in your database and in the cookie. Each time you read the cookie to log the user in, you check to see that both timestamps match. If they don't, deny the user. If they do, update the timestamps.

Using this method, any time your user returns to your site, all old cookies go stale. A hacker that has intercepted a cookie now has a worthless stale cookie because he does not know the exact time stamp in the current cookie. Of course, the hacker can use a fresh cookie as much as he wants until the user logs back in.

//check for cookie
if(isset($_COOKIE['remember_me'])) {
   // get hash and time stamp from cookie
   $hash = substr($_COOKIE['remember_me'],0,40);
   $last_visit = substr($_COOKIE['remember_me'],41);

   // query your db with $hash and $last_visit

   // if hash and time stamp match up
      // log in

      // store the current time stamp in a variable to use for both
      $time = date("Y-m-d H:i:s");
      // update the time stamp in your cookie
      $cookie = $pass . "-" . $time;
      setcookie('remember_me', $cookie, time()+60*60*24*100, '/');
      // update the time_stamp in your database
   else {
      // remove the remember me cookie
      setcookie('remember_me', '', time()-42000, '/')
   }

This method offers a small amount of security, and should certainly be used along side methods proposed in other answers. A hashed key should be stored in the cookie. A remember me cookie cannot be perfectly secure, so password re-entry should be required for any additional access to highly sensitive data or application features.

I also recommend naming your cookie something besides 'remember_me' to make it a little harder to find. While it does not add much security, if any, naming your cookie 'ht33424' takes just as long as naming it 'remember_me' or 'hack_me'.

Monday, August 2, 2021
 
0skar
answered 3 Months ago
37

Inheriting Singleton class in PHP is difficult, event in PHP 7.0, but you can do this with some changes on your class to work.

first make your Singleton class to abstract

abstract class Singleton {

}

change your $instance variable to array $instance(s)

private $instances = [];

Now change getInstance() method like below

public static function getInstance() {
  if (!isset(self::$instances[static::class]) {
    self::$instances[static::class] = new static();
  }

  return self::$instances[static::class];
}

And change your test

remember now you can't call Singleton:: getInstance() due to abstract

class SingletonChild extends Singleton {
}

class SingletonChildTwo extends SingletonChild {
}

$obj = SingletonChild::getInstance();
$obj_two = SingletonChildTwo::getInstance();
var_dump($obj === SingletonChild::getInstance()); // true
var_dump($obj === $obj_two); // will -> false
Monday, August 23, 2021
 
tiny
answered 2 Months ago
84

I'd go with autoloading. You don't have to worry about where you require_once() your classes if it does it automatically for you. All you have to do is start using the classes you expect to be there, and PHP will call your autoloader to make sure that the classes are loaded.

If you are more used to programming in an environment that has you import things at the top of each file, you might be more comfortable using require_once() at the top of all of your files. I almost prefer this over autoloading because it makes it very clear what each classes dependencies are. However, you get a lot of duplication which you might not enjoy.

Either way works. It is mostly a style choice.

Sunday, August 29, 2021
 
Vladimir Botka
answered 2 Months ago
67

Inner classes (static or not) have exactly the same access to their enclosing class' fields and methods as anonymous classes, the difference between static inner classes (actually called nested classes) and (regular, non-static) inner classes being that the static one need an explicit reference to an instance of the enclosing class to access something. Of course, when you need to do that, it's usually on the instance of the enclosing class that created the inner class, so it's easier and clearer to use a non-static inner class.

Examples:

  • Inner class (non-static)

    class A {
        private int field;
    
        private class B {
            public void doSomething() {
                field++; // Valid
            }
        }
    }
    
  • Nested class (i.e. "static inner class")

    class A {
        private int field;
    
        private static class B {
            public void doSomething(A a) {
                a.field++; // Valid
            }
        }
    }
    
  • Anonymous class

    class A {
        private int field;
    
        public void doSomething() {
            new Runnable() {
                @Override
                public void run() {
                    field++; // Valid
                }
            }
        }
    }
    

Whether you use that accessibility is another question. If you do access private fields of the enclosing class, there'll be an accessor generated, so it could impact the performance as the cost of calling a method is not the same as accessing a field, but it will probably be negligible in most cases. You should always write correct code first (both in terms of design and functionality) before doing micro-optimizations not based on any measurement. The JIT compiler does a lot of things for you anyway.

Wednesday, September 22, 2021
 
mgierw
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :