整理一个简单的短链算法,整理到自己的代码库中:
<?php /** * 短链服务 * @author vb2005xu */ class Service_ShortUrlGenerator { private static $table = 'short_url'; private static $list = array(); function __construct(array $config) { if ( empty($config['db']) ) { throw BaseError::invalid_parameters_error('key "db" not set'); } $this->_db = $config['db']; } /** * 获取指定用户创建的短链集合 * * @param int $uid * @param int $skip * @param int $limit * * @return array */ function getAllByUid( $uid , $skip=0, $limit=10 ) { $rows = DataSource::instance($this->_db)->select(self::$table,array( 'uid' => $uid, ),'*',null,$skip,$limit); return $rows; } /** * 获取指定用户创建的短链总数 * * @param int $uid * * @return int */ function getCountByUid( $uid ) { return DataSource::instance($this->_db)->count(self::$table,array( 'uid' => $uid, )); } /** * 通过短链标识 获取对应的 url * * @param string $identify * @param int $uid * * @return string */ function decode( $identify , $uid ) { $uid = intval($uid); if ( !empty($identify) && $uid > 0 ) { $identify = trim($identify); if ( strlen( $identify ) == 6 ) { if ( !isset( self::$list[$id] ) ) { $row = DataSource::instance($this->_db)->find_one(self::$table,array( 'uid' => $uid, 'identify' => $identify, ),'link'); self::$list[$identify] = empty($row['link']) ? NULL : $row['link']; } return self::$list[$identify]; } } return null; } /** * 返回6位的短链标识 * * @param string $url * * @return string */ function encode( $url , $uid ) { $uid = intval($uid); if ( !empty($url) && $uid > 0 ) { $url = trim($url); $identify = self::generate( $url ); # 放在此处做下缓存 self::$list[$identify] = $url; # 因为 uid + identify 做了唯一键索引,故此处不进行数据存在校验 DataSource::instance($this->_db)->insert(self::$table,array( 'uid' => $uid, 'identify' => $identify, 'link' => $link, 'create_at' => APP_START_TIMESTAMP, )); return $identify; } return null; } /** * 返回6位的短链标识 * * @param string $url * * @return string */ static function identify( $url ) { if ( empty($url) ) return FALSE; return self::code62( sprintf("%u", crc32($url)) ); } private static function code62($x) { $show = ''; while($x > 0) { $s = $x % 62; if ($s > 35) { $s = chr($s+61); } elseif ($s > 9 && $s <=35) { $s = chr($s + 55); } $show .= $s; $x = floor($x/62); } return $show; } }