0

Here is my situation:

On my home page I initialize my singleton this way:

mypage.com/index.php

<?php
    include ('includes/userfactory.php');
    session_start();

    $userFactory = UserFactory::instance();
    //make random number 10 to 100
    $userFactory->MakeRandomNumber();
    $userFactory->Print();
?>

<!DOCTYPE html>
<html>
    <head>
        My Page
    </head>

    <body>
        <li class="nav-item"><a href="newlink">go to new link</a></li>
    </body>
</html>

And when I click an href link to navigate to another page, on that page I try to call the singleton instance I previously created and then check my random number to see if it is the same as before.

mypage.com/newlink/index.php

<?php
    include ('../includes/userfactory.php');
    session_start();

    $userFactory = UserFactory::instance();
    $userFactory->Print();
?>

The thing is that on the second page the random number is not even generated yet, so it creates another instance of the supposed singleton.

This is my userfactory which extends Singleton class.

userfactory.php

<?php
include ('singleton.php');

class UserFactory extends Singleton 
{
    private $randomNumber = 0;
    private $isLive = false;

    public function Print()
    {
        echo "My random number is: ".$this->$randomNumber;
    }

    public function MakeRandomNumber()
    {
        if($this->$randomNumber == 0)
        {
            $this->$randomNumber = rand(10,100);
        }
    }
}
?>

And here is my Singleton pattern I copied from this thread

singleton.php

<?php

/**
 * Singleton Pattern.
 * 
 * Modern implementation.
 */
class Singleton
{
    /**
     * Call this method to get singleton
     */
    public static function instance()
    {
        static $instance = false;
        if( $instance === false )
        {
        // Late static binding (PHP 5.3+)
            $instance = new static();
        }
        
        return $instance;
    }

    /**
     * Make constructor private, so nobody can call "new Class".
     */
    private function __construct() {}

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}
?>

What am I doing wrong?

brunopava
  • 1
  • 3
  • This is a lot to digest. Could you possibly reformat your question to fit [mre]? It is a bit much to expect us to try and run all this and find the error. – The Grand J Sep 09 '20 at 01:32
  • @TheGrandJ Unfortunatelly this is it. I'm trying to access a singleton instance on multiple pages on my site and make this instance unique among them. How can I do that? – brunopava Sep 09 '20 at 01:35
  • 2
    Clicking on a link is changing the php process so you can't access your singleton anymore just by doing that. It is just like another user of your website is accessing your page. I suggest to store your object in a php session https://www.php.net/manual/en/reserved.variables.session.php – Julien Bourdic Sep 09 '20 at 01:47
  • @JulienBourdic Thanks for the insight! It solved perfectly my problem, but still my singleton class had a bug. – brunopava Sep 09 '20 at 02:25

1 Answers1

0

SOLVED

Remove these lines from singleton.php

/**
 * Make sleep magic method private, so nobody can serialize instance.
 */
private function __sleep() {}

/**
 * Make wakeup magic method private, so nobody can unserialize instance.
 */
private function __wakeup() {}

Save $_SESSION example using classes UserFactory and Singleton

test.php

<?php
include ('includes/userfactory.php');

session_start();
if(!isset($_SESSION["singleton"]))
{
    $singleton = UserFactory::instance();
    $_SESSION['singleton'] = $singleton;
    $_SESSION['singleton']->MakeRandomNumber();
}else
{
    $_SESSION['singleton']->Print();
}

?>
<!DOCTYPE html>
<html>
    <head>
        My Page
    </head>

    <body>
        <li class="nav-item"><a href="test2.php">TEST2</a></li>
    </body>
</html>

test2.php

<?php
include ('includes/userfactory.php');

session_start();
if(isset($_SESSION["singleton"]))
{
    $_SESSION['singleton']->Print();
}
?>

<!DOCTYPE html>
<html>
    <head>
        My Page 2
    </head>

    <body>
        <li class="nav-item"><a href="test.php">TEST</a></li>
    </body>
</html>

WITH GREAT POWER COMES GREAT RESPONSIBILITY

Use your new powers well young padawans.

brunopava
  • 1
  • 3