一、所需环境
开发环境:CentOS 5.4
运行环境:Nginx+PHP+Redis
二、运行环境的部署
1、Nginx+PHP 环境的安装
参考:http://www.s135.com/nginx_php_v6
2、Redis 环境的安装
Redis服务端的安装
cd /usr/local/src/
#下载redis
wget http://redis.googlecode.com/files/redis-2.2.12.tar.gz#解压
tar zxvf redis-2.2.12.tar.gz
cp -R redis-2.2.12 /usr/local/
mv /usr/local/redis-2.2.12/ /usr/local/redis
#可查看帮助文件 INSTALL
cd /usr/local/redis/src
make#make命令执行完成后,会在src目录下生成5个可执行文件,分别是redis-server、redis-cli、redis-benchmark、redis-check-aof、redis-check-dump,它们的作用如下:
#redis-server:Redis服务器的daemon启动程序
#redis-cli:Redis命令行操作工具。当然,你也可以用telnet根据其纯文本协议来操作
#redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能
#redis-check-aof:更新日志检查
redis-check-dump:用于本地数据库检查make install
#执行make install ,会执行如下的命令
mkdir -p /usr/local/bin
cp -p redis-server /usr/local/bin
cp -p redis-benchmark /usr/local/bin
cp -p redis-cli /usr/local/bin
cp -p redis-check-dump /usr/local/bin
cp -p redis-check-aof /usr/local/bin
#我习惯手动运行下面的命令:
cp /usr/local/redis/src/redis-server /usr/local/redis/
cp /usr/local/redis/src/redis-cli /usr/local/redis/
cp /usr/local/redis/src/redis-benchmark /usr/local/redis/#配置redis.conf
根据实际情况来配置
#运行redis
/usr/local/redis/redis-server /usr/local/redis/redis.conf
phpredis模块的安装
#下载phpredis
wget https://nodeload.github.com/nicolasff/phpredis/tarball/master
tar zxvf nicolasff-phpredis-2.1.3-20-g9e1d068.tar.gz
mv nicolasff-phpredis-9e1d068/ phpredis
cd phpredis/
#生成扩展文件redis.so
/usr/local/webserver/php/bin/phpize
./configure –with-php-config=/usr/local/webserver/php/bin/php-config
make
make install#make install 后会得到如下结果:
Installing shared extensions: /usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/
接下来在php.ini中添加PHP的扩展目录(如果已添加则不用再次添加)
extension_dir = “/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/”
接着添加如下代码:
extension=redis.so
执行以下命令,即可看到加载的redis模块:
/usr/local/webserver/php/sbin/php-fpm reload
三、程序代码的实现
函数文件源码:
/*
*common_function.php
*/
//短url 加密算法
function shortUrl($url, $salt = '') {
$base62_units = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$base2_unit30 = (('0x' . substr(md5($url . $salt), 0, 8)) * 1) & 0x3fffffff;
$base62_unit6 = '';
while ($base2_unit30 > 0) {
$base62_unit6 .= $base62_units[$base2_unit30 & 61];
$base2_unit30 >>= 5;
}
return $base62_unit6;
}
//解析url
function parseUrl($url){
$parse_url_arr = explode(':',($url));
$url_pro_arr = array('http','https','ftp','svn');
if(in_array(strtolower($parse_url_arr[0]),$url_pro_arr)){
return $url;
}else{
return $url = 'http://'.$url;
}
}
//获取短url方法
function getShortUrl($url){
if(empty($url)) return false;
$tmp_url = 'http://www.lamp100.cn/index.php?action=setUrl&url='.urlencode($url);
// 1. 初始化
$ch = curl_init();
// 2. 设置选项,包括URL
curl_setopt($ch, CURLOPT_URL, $tmp_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'xikang:123456');
curl_setopt($ch, CURLOPT_HEADER, 0);
// 3. 执行并获取HTML文档内容
$short_url = curl_exec($ch);
// 4. 释放curl句柄
curl_close($ch);
return $short_url;
}
index.php 主入口文件:
header('Content-Type: text/html; charset=utf-8');
ini_set('display_errors',1);
include_once('common_function.php');
define('REDIS_HOST','127.0.0.1');
define('REDIS_PORT',6379);
define('AUTH_KEY','lamp100&^%$#@!');
define('PRE_URL','http://lamp100.cn/');
define('ERROR_URL','http://www.lamp100.com');
define('VERSION','v0.1:');
define('MAX_ID','MAX_ID:');
define('CHECKMD5','CHECKMD5:');
$redis = new Redis();
$redis->connect(REDIS_HOST,REDIS_PORT);
$action = trim($_GET['action']);
$url = trim($_GET['url']);
//解析url
$url = parseUrl($url);
$short_url = trim($_GET['short_url']);
if($action == 'setUrl'){
//检测MD5表中是否有记录
if(!$redis->get(CHECKMD5.md5($url))){
//判断是否有最大值id
$max_id = $redis->get(MAX_ID.'id');
if(!$max_id){
$redis->set(MAX_ID.'id',10000);
}else{
//$url_key = shortUrl($url,AUTH_KEY);
include_once('hex_conver.class.php');
$hex = new Hex_conver();
$max_id = $max_id + 1;
$redis->set(MAX_ID.'id',$max_id);
$url_key = $hex->hex10to62($max_id);
$redis->set(VERSION.$url_key,$url);
//存储到md5表里
$redis->set(CHECKMD5.md5($url),$url_key);
}
}else{
$url_key = $redis->get(CHECKMD5.md5($url));
}
echo '<a title="'.$url.'" href="'.$url.'" target="_blank">'.PRE_URL.$url_key.'</a>';
}elseif($action == 'getUrl'){
if(empty($short_url)){
echo '请确认域名后面的字符串是否正确!';
exit;
}
$url_res = $redis->get(VERSION.$short_url);
if($url_res){
echo '<a title="'.$url_res.'" href="'.$url_res.'" target="_blank">'.PRE_URL.$short_url.'</a>';
}else{
echo '该短名称<
<span style="color: red;"> '.$short_url.' </span>还未被使用!';
}
}elseif($action == 'redirect'){
$url_res = $redis->get(VERSION.$short_url);
if(!empty($url_res)){
header('location:'. $url_res);
}else{
header('location:'.ERROR_URL);
}
}elseif($action == 'demo'){
$url = trim($_POST['url'])?trim($_POST['url']):$_GET['url'];
if(!empty($url)){
$short_url = getShortUrl($url);
}else{
$short_url = '';
}
include ('demo.php');
}else{
echo '您请求的操作不存在';
exit;
}
hex_conver.class.php 源码:
class Hex_conver{
const KeyCode = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
public function __construct(){
}
/**
* 将62进制的数字字符串转为10进制的数字字符串
* @param $m string 62进制的数字字符串
* @param $len integer 返回字符串长度,如果长度不够用0填充,0为不填充
* @return string
* @author
*/
public function hex62to10($m, $len = 0) {
$m = (string)$m;
$hex2 = '';
$Code = self::KeyCode;
for($i = 0, $l = strlen($Code); $i < $l; $i++) {
$KeyCode[] = $Code[$i];
}
$KeyCode = array_flip($KeyCode);
for($i = 0, $l = strlen($m); $i < $l; $i++) {
$one = $m[$i];
$hex2 .= str_pad(decbin($KeyCode[$one]), 6, '0', STR_PAD_LEFT);
}
$return = bindec($hex2);
return $return;
}
/**
* 将10进制的数字字符串转为62进制的数字字符串
* @param $m string 10进制的数字字符串
* @param $len integer 返回字符串长度,如果长度不够用0填充,0为不填充
* @return string
* @author
*/
public function hex10to62($m, $len = 0) {
$KeyCode = self::KeyCode;
$hex2 = decbin($m);
$hex2 = $this->str_rsplit($hex2, 6);
$hex64 = array();
foreach($hex2 as $one) {
$t = bindec($one);
$hex64[] = $KeyCode[$t];
}
$return = preg_replace('/^0*/', '', implode('', $hex64));
if($len) {
$clen = strlen($return);
if($clen >= $len) {
return $return;
}
else {
return str_pad($return, $len, '0', STR_PAD_LEFT);
}
}
return $return;
}
/**
* 功能和PHP原生函数str_split接近,只是从尾部开始计数切割
* @param $str string 需要切割的字符串
* @param $len integer 每段字符串的长度
* @return array
* @author
*/
protected function str_rsplit($str, $len = 1) {
if($str == null || $str == false || $str == '') return false;
$strlen = strlen($str);
if($strlen <= $len) return array($str);
$headlen = $strlen % $len;
if($headlen == 0) {
return str_split($str, $len);
}
$return = array(substr($str, 0, $headlen));
return array_merge($return, str_split(substr($str, $headlen), $len));
}
四、实例运行
以上内容来自互联网,在此表示感谢!