每个 class 实例化的唯一随机数

Unique random number for every class instantiation

我想通过 rand() 为我的 class 的每个实例生成一个随机 ID。我希望它是独一无二的。这是我写的,但这不起作用。

class Computer
{
    private $id = 0; // placeholder for ID
    private $id_list = []; // placeholder to store used IDs

    public function __construct()
    {
        $this->checkID();
    }

    private function checkID()
    {
        $this->id = rand(1,3);
        if (!in_array($this->id, $this->id_list))
        {
            array_push($this->id_list, $this->id);
        } else {
            $this->checkID();
        }
    }
}

我有意尝试生成低值,例如 rand(1,3),我得到了三个 ID 为 2、2、1 的对象。所以它不起作用。

我认为这是因为对于 class $id_list 数组的每个新实例都变为空。但我见过人们做几乎相同的事情。声明一个 $counter 变量并将 $this->counter++ 放入 __construct 方法中。那有什么区别呢?

这样使用的$counter变量不是随机的,而是唯一的。它只是在创建对象时对其进行计数,根据您的喜好从 0 或 1 开始。不同之处在于 class 的所有对象都在访问同一个变量。为此,变量必须声明为静态的,如下所示:

public static $counter = 0;

function __construct() 
    self::$counter++;
}

要生成一个同样唯一的随机数,您必须编写一个子例程,将生成的数字与每个实例化对象的 ID 进行比较。这可能会很快变得低效,我不推荐这样做。但如果你打算这样做,它可能看起来像这样:

class Computer
{
    private $id = 0; // placeholder for ID
    private static $id_list = []; // placeholder to store used IDs

    public function __construct()
    {
        $this->id = self::checkID();
    }

    private static function checkID()
    {
        $newID = rand(1,10000);
        if (!in_array($newID, self::$id_list))
        {
            array_push(self::$id_list, $newID);
            return $newID;
        } else {
            self::checkID();
        }
    }
}

您需要将 $id_list 设为静态,以便它保留存储的值,例如:

class Computer
{
    private $id = 0; // placeholder for ID
    private static $id_list = []; // placeholder to store used IDs

    public function __construct()
    {
        $this->checkID();
        print_r(self::$id_list);
    }

    private function checkID()
    {
        $this->id = rand(1,3);
        if (!in_array($this->id, self::$id_list))
        {
            array_push(self::$id_list, $this->id);
        } else {
            $this->checkID();
        }
    }
}
for($i = 0; $i < 10; $i++){
    new Computer();
}

我添加了打印线来展示结果,但你应该明白这一点。

使用可以使用spl_object_hash()函数:

This function returns a unique identifier for the object. This id can be used as a hash key for storing objects, or for identifying an object, as long as the object is not destroyed. Once the object is destroyed, its hash may be reused for other objects.

每次构造对象都可以调用spl_object_hash():

class Computer
{
    private $id = "";            // placeholder for a unique random Id

    public function __construct()
    {
        $this->id = spl_object_hash( $this );
    }
}

注意spl_object_hash()返回值的唯一性有一个'weak'点:

Once the object is destroyed, its hash may be reused for other objects.

在这种情况下,您可以使用如下代码构建您自己的 hashing 机制:

class Computer
{
    private $id = "";            // placeholder for a unique random Id
    private static $seed = 0;    //placeholder for the seed

    public function __construct()
    {
        self::$seed++;
        $this->id = hash('md5', get_class($this) . self::$seed );
    }
 } 

实际上,不需要检查重复的 ID,因为 md5 哈希在 2^128!

中的冲突概率为 1