UniqueGenerator.php 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. <?php
  2. namespace Faker;
  3. /**
  4. * Proxy for other generators, to return only unique values. Works with
  5. * Faker\Generator\Base->unique()
  6. */
  7. class UniqueGenerator
  8. {
  9. protected $generator;
  10. protected $maxRetries;
  11. protected $uniques = array();
  12. /**
  13. * @param Generator $generator
  14. * @param integer $maxRetries
  15. */
  16. public function __construct(Generator $generator, $maxRetries = 10000)
  17. {
  18. $this->generator = $generator;
  19. $this->maxRetries = $maxRetries;
  20. }
  21. /**
  22. * Catch and proxy all generator calls but return only unique values
  23. * @param string $attribute
  24. * @return mixed
  25. */
  26. public function __get($attribute)
  27. {
  28. return $this->__call($attribute, array());
  29. }
  30. /**
  31. * Catch and proxy all generator calls with arguments but return only unique values
  32. * @param string $name
  33. * @param array $arguments
  34. * @return mixed
  35. */
  36. public function __call($name, $arguments)
  37. {
  38. if (!isset($this->uniques[$name])) {
  39. $this->uniques[$name] = array();
  40. }
  41. $i = 0;
  42. do {
  43. $res = call_user_func_array(array($this->generator, $name), $arguments);
  44. $i++;
  45. if ($i > $this->maxRetries) {
  46. throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
  47. }
  48. } while (array_key_exists(serialize($res), $this->uniques[$name]));
  49. $this->uniques[$name][serialize($res)]= null;
  50. return $res;
  51. }
  52. }