>  기사  >  백엔드 개발  >  php_php 팁에서 고유 숫자 ID를 생성하는 방법 요약

php_php 팁에서 고유 숫자 ID를 생성하는 방법 요약

WBOY
WBOY원래의
2016-05-16 20:04:231431검색

고유 디지털 ID 생성 문제와 관련하여 Rand를 사용하여 난수를 생성한 다음 데이터베이스에 쿼리하여 그러한 숫자가 있는지 확인해야 합니까? 시간이 좀 많이 걸리는 것 같습니다. 다른 방법은 없을까요?

물론 그렇지 않습니다. 실제로 해결 방법은 두 가지가 있습니다.

1. 데이터베이스가 아닌 PHP만 사용하는 경우 타임스탬프 난수를 사용하는 것이 가장 좋으며 반복되지 않습니다.

2. 데이터베이스를 사용해야 하는 경우 다른 데이터도 이 ID와 연결해야 합니다. 그런 다음 MySQL 데이터베이스의 테이블 ID에 AUTO_INCREMENT(자동 증가) 속성을 지정합니다. 데이터 조각이 삽입될 때마다 ID는 자동으로 1로 증가한 다음 mysql_insert_id() 또는 LAST_INSERT_ID()를 사용하여 자동을 반환합니다. -증가된 ID.

물론, 이 문제에 대한 기성 솔루션이 이미 있습니다. php uuid 확장을 사용하면 이 문제를 완벽하게 해결할 수 있습니다. 고유하고 완전한 디지털 서명을 생성할 수 있습니다. .

작곡기를 사용하지 않는 경우

https://github.com/lootils/uuid, 를 참고하세요.

작곡가를 기반으로 한 프로젝트라면

https://github.com/ramsey/uuid를 참고하세요.

특정 소스코드는 옮기지 않겠습니다. 친구들이 직접 내려서 사용해도 됩니다

PHP에서 생성된 고유 식별자 코드 예:


< &#63; 
//生成唯一标识符  
//sha1()函数, "安全散列算法(SHA1)"  
function create_unique() {  
$data = $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']  
.time() . rand();  
return sha1($data);  
//return md5(time().$data);  
//return $data;  
} 
&#63;> 
PHP는 고유 식별자 함수 설명 및 예제를 생성합니다


< &#63;  
$newhash = create_unique();  
echo $newhash;  
&#63;>
한 가지 더 말씀드리겠습니다

/*
 * 信号量(Semaphore)。
 * 这是一个包装类,用于解决不同平台下对“信号量”的不同实现方式。
 * 目前这个类只是象征性的,在 Windows 平台下实际是空跑(并没有真的实现互斥)。
 */
class SemWrapper
{
  private $hasSemSupport;
  private $sem;
  const SEM_KEY = 1;

  public function __construct()
  {
    $this->hasSemSupport = function_exists( 'sem_get' );
    if ( $this->hasSemSupport ) {
      $this->sem = sem_get( self::SEM_KEY );
    }
  }

  public function acquire() {
    if ( $this->hasSemSupport ) {
      return sem_acquire( $this->sem );
    }
    return true;
  }

  public function release() {
    if ( $this->hasSemSupport ) {
      return sem_release( $this->sem );
    }
    return true;
  }
}

/*
 * 顺序号发生器。
 */
class SeqGenerator
{
  const SHM_KEY = 1;

  /**
   * 对顺序号发生器进行初始化。
   * 仅在服务器启动后的第一次调用有效,此后再调用此方法没有实际作用。
   * @param int $start 产生顺序号的起始值。
   * @return boolean 返回 true 表示成功。
   */
  static public function init( $start = 1 )
  {
    // 通过信号量实现互斥,避免对共享内存的访问冲突
    $sw = new SemWrapper;
    if ( ! $sw->acquire() ) {
      return false;
    }

    // 打开共享内存
    $shm_id = shmop_open( self::SHM_KEY, 'n', 0644, 4 );
    if ( empty($shm_id) ) {
      // 因使用了 'n' 模式,如果无法打开共享内存,可以认为该共享内存已经创建,无需再次初始化
      $sw->release();
      return true;
    }

    // 在共享内存中写入初始值
    $size = shmop_write( $shm_id, pack( 'L', $start ), 0 );
    if ( $size != 4 ) {
      shmop_close( $shm_id );
      $sw->release();
      return false;
    }

    // 关闭共享内存,释放信号量
    shmop_close( $shm_id );
    $sw->release();
    return true;
  }

  /**
   * 产生下一个顺序号。
   * @return int 产生的顺序号
   */
  static public function next()
  {
    // 通过信号量实现互斥,避免对共享内存的访问冲突
    $sw = new SemWrapper;
    if ( ! $sw->acquire() ) {
      return 0;
    }

    // 打开共享内存
    $shm_id = shmop_open( self::SHM_KEY, 'w', 0, 0 );
    if ( empty($shm_id) ) {
      $sw->release();
      return 0;
    }

    // 从共享内存中读出顺序号
    $data = shmop_read( $shm_id, 0, 4 );
    if ( empty($data) ) {
      $sw->release();
      return 0;
    }

    $arr = unpack( 'L', $data );
    $seq = $arr[1];

    // 把下一个顺序号写入共享内存
    $size = shmop_write( $shm_id, pack( 'L', $seq + 1 ), 0 );
    if ( $size != 4 ) {
      $sw->release();
      return 0;
    }

    // 关闭共享内存,释放信号量
    shmop_close( $shm_id );
    $sw->release();
    return $seq;
  }
}

$a = SeqGenerator::init( time() );
var_dump($a);

for ( $i=0; $i < 10; $i++ ) {
  $seq = SeqGenerator::next();
  var_dump($seq);
}
자, 오늘은 여기까지 하겠습니다. PHP를 배우는 모든 분들께 도움이 되었으면 좋겠습니다

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.