1<?php 2namespace Hidehalo\Nanoid; 3 4class Client 5{ 6 /** 7 * Random mode flags 8 * 9 * @const MODE_NORMAL 1 10 * @const MODEL_DYNAMIC 2 11 */ 12 const MODE_NORMAL = 1; 13 const MODE_DYNAMIC = 2; 14 /** 15 * @param string $alphabet Symbols to be used in ID. 16 * @param integer $size number of symbols in ID. 17 */ 18 protected $alphbet; 19 protected $size; 20 21 /** 22 * @var CoreInterface $core Core dynamic random 23 */ 24 private $core; 25 /** 26 * @var GeneratorInterface $generator Random Btyes Generator 27 */ 28 protected $generator; 29 30 /** 31 * Constructor of Client 32 * 33 * @codeCoverageIgnore 34 * @param integer $size 35 * @param GeneratorInterface $generator 36 */ 37 public function __construct($size = 21, GeneratorInterface $generator = null) 38 { 39 $this->size = $size > 0 ? $size : 21; 40 $this->generator = $generator?:new Generator(); 41 $this->core = new Core(); 42 $this->alphbet = CoreInterface::SAFE_SYMBOLS; 43 } 44 45 /** 46 * Generate nanoid via optional modes 47 * 48 * @param integer $size 49 * @param integer $mode Client::MODE_NORMAL|Client::MODE_DYNAMIC 50 * @return string 51 */ 52 public function generateId($size = 0, $mode = self::MODE_NORMAL) 53 { 54 $size = $size>0? $size: $this->size; 55 switch ($mode) { 56 case self::MODE_DYNAMIC: 57 return $this->core->random($this->generator, $size, $this->alphbet); 58 default: 59 return $this->normalRandom($size); 60 } 61 } 62 63 /** 64 * The original API of nanoid. Use it be careful, Please make sure 65 * you have been implements your custom GeneratorInterface as correctly. 66 * Otherwise use the build-in default random bytes generator 67 * 68 * @param GeneratorInterface $generator 69 * @param integer $size 70 * @param string $alphabet default CoreInterface::SAFE_SYMBOLS 71 * @return string 72 */ 73 public function formattedId($alphabet, $size = 0, GeneratorInterface $generator = null) 74 { 75 $alphabet = $alphabet?:CoreInterface::SAFE_SYMBOLS; 76 $size = $size>0? $size: $this->size; 77 $generator = $generator?:$this->generator; 78 79 return $this->core->random($generator, $size, $alphabet); 80 } 81 82 /** 83 * Backwards-compatible method name. 84 * 85 * @param string $alphabet 86 * @param integer $size 87 * @param GeneratorInterface $generator 88 * 89 * @return string 90 * @since 1.0.0 91 */ 92 public function formatedId($alphabet, $size = 0, GeneratorInterface $generator = null) 93 { 94 $size = $size>0? $size: $this->size; 95 96 return $this->formattedId($alphabet, $size, $generator); 97 } 98 99 /** 100 * Generate secure URL-friendly unique ID. 101 * By default, ID will have 21 symbols to have same collisions probability 102 * as UUID v4. 103 * 104 * @see https://github.com/ai/nanoid/blob/master/non-secure/index.js#L19 105 * @param integer $size 106 * @return string 107 */ 108 private function normalRandom($size) 109 { 110 $id = ''; 111 while (1 <= $size--) { 112 $rand = mt_rand()/(mt_getrandmax() + 1); 113 $id .= $this->alphbet[$rand*64 | 0]; 114 } 115 116 return $id; 117 } 118} 119