0

I have the following code in a class that generates a random string.

public static function codeGenerator() {
    $length = 7;
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $output = null;

    for ($i = 0; $i < $length; $i++) {
        $output .= $characters[mt_rand(0, strlen($characters) - 1)];
    }
    return $output;
}

I would like to use the same random generated string in two other functions in the same class. Unfortunately, I'm getting two different values every time. I need to have the same values for the same string.

Dharman
  • 30,962
  • 25
  • 85
  • 135
ACDC
  • 119
  • 1
  • 7
  • So why don't you inject the randomly generated value into the relevant services? Call `codeGenerator` on the very "outside", store it in a variable, and pass it into the relevant services via dependency injection. That being said: You can set the seed of the random generator. – k0pernikus May 03 '20 at 00:02
  • https://www.php.net/mt_srand – k0pernikus May 03 '20 at 00:04

3 Answers3

1

Create a class property that stores that value and then refer to it whenever you need it.

Psuedocode:

class Whatever 
{
    protected $random;

    public function codeGenerator() {
      $length = 7;
      $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
      $output = null;

      for ($i = 0; $i < $length; $i++) {
        $output .= $characters[mt_rand(0, strlen($characters) - 1)];
      }
      $this->random = $output;
      return $output;
    }

    public function doSomething() 
    {
        echo $this->random; // replace this with other business logic
    }
}

$class = new Whatever();
$code = $class->codeGenerator();
$class->doSomething();
John Conde
  • 217,595
  • 99
  • 455
  • 496
  • The function is static in OPs code. Therefore when it is run it will not recognise the `$this` property – Martin May 03 '20 at 00:04
  • I don't know as I don't know how they plan to use this. That is why it is pseudocode. It's just to demonstrate the principle. – John Conde May 03 '20 at 00:04
1

The precise way to do it depends a lot on how your code is structured. I essence, what you will do is that you will call this function just once, store the result in a variable, and then later use just that variable instead of calling the function again. But where that variable should live - that's up to you. In general, try to avoid global variables and static class members (which are just another kind of global variable). Pass it along as function parameters, if you can. But we'll need to know more of your code to give a more precise answer.

Vilx-
  • 104,512
  • 87
  • 279
  • 422
1

While the words of Vilx are correct, one way around this is to use a static variable in the class:

Because your method is static it is not really, truly inside any "class" but is more like a global. Therefore It can't "save" data between each time it runs, unless you use a "static" variable outside of the scope of the method, but within this class, alongside your "static" method.

Your life becomes much easier if you use a non-static class method reference (or if you use a superglobal such as a $_SESSION variable). It all depends on what you're actually doing with this method.

However, the example code below defines a string and then repeat calls that string in the same PHP script, as exampled.

Class with Static Variable:

<?php

class twister {
    public static $VALUEZ = ''; //this holds your generated code value.

public static function codeGenerator() {

    if(empty(self::$VALUEZ)){
        // Is unset so generate this value for the first time.
        $length = 7;
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $output = null;

        for ($i = 0; $i < $length; $i++) {
            $output .= $characters[mt_rand(0, strlen($characters) - 1)];
        }
    self::$VALUEZ = $output;
    }
    else {
        // value is not empty so simply throw it back out.  
        $output = self::$VALUEZ;
    }
    return $output;
} // close method.



} //close class

$claz = new twister();

print $claz::codeGenerator();
print "\n";
print $claz::codeGenerator();
print "\n";
print $claz::codeGenerator();

Output:

DVMbN0L
DVMbN0L
DVMbN0L

Live Code

Martin
  • 22,212
  • 11
  • 70
  • 132