当前位置: 编程技术>php
本页文章导读:
▪php 短链接算法收集与分析
短链接就不说了,大家已经都清楚了,如下所示就是短链接: 新浪微博 http://t.cn/SVpONM 腾讯微博 http://url.cn/302yor Yun.io http://d.yun.io/PNri2v 短链接的好处:1、内容需要;2、用户友好;3、便于.........
▪php的大小写敏感问题整理
PHP对大小写敏感问题的处理比较乱,写代码时可能偶尔出问题,所以这里总结一下。 但我不是鼓励大家去用这些规则。 推荐大家始终坚持“大小写敏感”,遵循统一的代码规范。 一、大小.........
▪php读取mysql乱码,用set names XXX解决的原理分享
先说MySQL的字符集问题。Windows下可通过修改my.ini内的 PHP代码 代码如下: [mysql] default-character-set=utf8 //客户端的默认字符集 [mysqld] default-character-set=utf8 //服务器端默认的字符集 假设我们把两.........
[1]php 短链接算法收集与分析
来源: 互联网 发布时间: 2013-11-30
短链接就不说了,大家已经都清楚了,如下所示就是短链接:
新浪微博 http://t.cn/SVpONM
腾讯微博 http://url.cn/302yor
Yun.io http://d.yun.io/PNri2v
短链接的好处:1、内容需要;2、用户友好;3、便于管理。
如何实现呢,大概有三个步骤:
1、定义一个URL映射算法,可以将长的URL映射成短字符串;
2、使用一个存储(数据库?NoSQL?)来存储完成的映射;
3、实现自己的URL映射算法;
一般来说,第三步是我们比较头疼的,如何将一个长的URL字符串,映射成一个较短的字符串呢。我总结了三种办法:
普通实现
我想以前大家学习过十进制和二进制的互相转换,或者十进制和十六进制的互相转换,那么为了更短,我们可以使用62进制,对于一个数字ID进行转码,转换成一个短字符串。
这种做法的缺点是没有办法保证所有链接都是固定的位数的长度,而且在高并发的情况下,如何保证能够快速分发是个问题。
具体实现方法:
/**
* 利用62进制对数字ID进行短链接编码,缺点不能保证每个短链接是固定长度
*
* @author wanshiqiang<wangshiqiang@360.cn>
* @param integer $integer
* @param string $base
*/
private function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)
{
$length = strlen($base);
while($integer > $length - 1)
{
$out = $base[fmod($integer, $length)] . $out;
$integer = floor( $integer / $length );
}
return $base[$integer] . $out;
}
/**
* 对62进制编码的短链接进行解码
*
* @author wangshiqiang<wangshiqiang@360.cn>
* @param string $string
* @param string $base
*/
private function getIDFromShortenedURL ($string, $base = ALLOWED_CHARS)
{
$length = strlen($base);
$size = strlen($string) - 1;
$string = str_split($string);
$out = strpos($base, array_pop($string));
foreach($string as $i => $char)
{
$out += strpos($base, $char) * pow($length, $size - $i);
}
return $out;
}
文艺实现
算法描述:使用6个字符来表示短链接,我们使用ASCII字符中的'a'-'z','0'-'5',共计32个字符做为集合。每个字符有32种状态,六个字符就可以表示32^6(1073741824),那么如何得到这六个字符,描述如下:
对传入的长URL进行Md5,得到一个32位的字符串,这个字符串变化很多,是16的32次方,基本上可以保证唯一性。将这32位分成四份,每一份8个字符,这时机率变成了16的8次方,是4294967296,这个数字碰撞的机率也比较小啦,关键是后面的一次处理。我们将这个8位的字符认为是16进制整数,也就是1*('0x'.$val),然后取0-30位,每5个一组,算出他的整数值,然后映射到我们准备的32个字符中,最后就能够得到一个6位的短链接地址。
PHP实现如下:
function shorten( $long_url )
{
$base32 = "abcdefghijklmnopqrstuvwxyz012345";
$hex = md5( $long_url );
$hexLen = strlen( $hex );
$subHexLen = $hexLen / 8;
$output = array();
for( $i = 0; $i < $subHexLen; $i++ )
{
$subHex = substr( $hex, $i * 8, 8 );
$subHex = 0x3FFFFFFF & ( 1 * ('0x' . $subHex ) );
$out = '';
for( $j = 0; $j < 6; $j++ )
{
$val = 0x0000001F & $int;
$out .= $base32[$val];
$int = $int >> 5;
}
$output[] = $out;
}
return $output;
}
二逼实现
下面这个函数使用了纯随机的方式来生成一个短链接,虽然我们可以通过查询操作来确保不重复使用短链接,可是... 这样真的靠谱吗~~
function random($length, $pool = '') {
$random = '';
if (empty($pool)) { $pool = 'abcdefghkmnpqrstuvwxyz'; $pool .=
'23456789'; }
srand ((double)microtime()*1000000);
for($i = 0; $i < $length; $i++) { $random .=
substr($pool,(rand()%(strlen ($pool))), 1); }
return $random;
}
新浪微博 http://t.cn/SVpONM
腾讯微博 http://url.cn/302yor
Yun.io http://d.yun.io/PNri2v
短链接的好处:1、内容需要;2、用户友好;3、便于管理。
如何实现呢,大概有三个步骤:
1、定义一个URL映射算法,可以将长的URL映射成短字符串;
2、使用一个存储(数据库?NoSQL?)来存储完成的映射;
3、实现自己的URL映射算法;
一般来说,第三步是我们比较头疼的,如何将一个长的URL字符串,映射成一个较短的字符串呢。我总结了三种办法:
普通实现
我想以前大家学习过十进制和二进制的互相转换,或者十进制和十六进制的互相转换,那么为了更短,我们可以使用62进制,对于一个数字ID进行转码,转换成一个短字符串。
这种做法的缺点是没有办法保证所有链接都是固定的位数的长度,而且在高并发的情况下,如何保证能够快速分发是个问题。
具体实现方法:
代码如下:
/**
* 利用62进制对数字ID进行短链接编码,缺点不能保证每个短链接是固定长度
*
* @author wanshiqiang<wangshiqiang@360.cn>
* @param integer $integer
* @param string $base
*/
private function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)
{
$length = strlen($base);
while($integer > $length - 1)
{
$out = $base[fmod($integer, $length)] . $out;
$integer = floor( $integer / $length );
}
return $base[$integer] . $out;
}
/**
* 对62进制编码的短链接进行解码
*
* @author wangshiqiang<wangshiqiang@360.cn>
* @param string $string
* @param string $base
*/
private function getIDFromShortenedURL ($string, $base = ALLOWED_CHARS)
{
$length = strlen($base);
$size = strlen($string) - 1;
$string = str_split($string);
$out = strpos($base, array_pop($string));
foreach($string as $i => $char)
{
$out += strpos($base, $char) * pow($length, $size - $i);
}
return $out;
}
文艺实现
算法描述:使用6个字符来表示短链接,我们使用ASCII字符中的'a'-'z','0'-'5',共计32个字符做为集合。每个字符有32种状态,六个字符就可以表示32^6(1073741824),那么如何得到这六个字符,描述如下:
对传入的长URL进行Md5,得到一个32位的字符串,这个字符串变化很多,是16的32次方,基本上可以保证唯一性。将这32位分成四份,每一份8个字符,这时机率变成了16的8次方,是4294967296,这个数字碰撞的机率也比较小啦,关键是后面的一次处理。我们将这个8位的字符认为是16进制整数,也就是1*('0x'.$val),然后取0-30位,每5个一组,算出他的整数值,然后映射到我们准备的32个字符中,最后就能够得到一个6位的短链接地址。
PHP实现如下:
代码如下:
function shorten( $long_url )
{
$base32 = "abcdefghijklmnopqrstuvwxyz012345";
$hex = md5( $long_url );
$hexLen = strlen( $hex );
$subHexLen = $hexLen / 8;
$output = array();
for( $i = 0; $i < $subHexLen; $i++ )
{
$subHex = substr( $hex, $i * 8, 8 );
$subHex = 0x3FFFFFFF & ( 1 * ('0x' . $subHex ) );
$out = '';
for( $j = 0; $j < 6; $j++ )
{
$val = 0x0000001F & $int;
$out .= $base32[$val];
$int = $int >> 5;
}
$output[] = $out;
}
return $output;
}
二逼实现
下面这个函数使用了纯随机的方式来生成一个短链接,虽然我们可以通过查询操作来确保不重复使用短链接,可是... 这样真的靠谱吗~~
代码如下:
function random($length, $pool = '') {
$random = '';
if (empty($pool)) { $pool = 'abcdefghkmnpqrstuvwxyz'; $pool .=
'23456789'; }
srand ((double)microtime()*1000000);
for($i = 0; $i < $length; $i++) { $random .=
substr($pool,(rand()%(strlen ($pool))), 1); }
return $random;
}
Technorati 标签: 短链接,Short Url,映射,哈希
参考资料:
1、微博短地址原理解析
2、微博短域名原理及作用
3、Yours.org
4、Free PHP URL Shorten script that kicks ass
5、PHP Short Url Algorithm Implementation
6、Implement your own short URL
7、短网址算法初步汇总
8、Short Url 实现方式
[2]php的大小写敏感问题整理
来源: 互联网 发布时间: 2013-11-30
PHP对大小写敏感问题的处理比较乱,写代码时可能偶尔出问题,所以这里总结一下。
但我不是鼓励大家去用这些规则。 推荐大家始终坚持“大小写敏感”,遵循统一的代码规范。
一、大小写敏感
1. 变量名区分大小写
所有变量均区分大小写,包括普通变量以以及$_GET, $_POST, $_REQUEST, $_COOKIE, $_SESSION, $GLOBALS, $_SERVER, $_FILES, $_ENV等;
<?php
$abc = 'abcd';
echo $abc; //输出 'abcd'
echo $aBc; //无输出
echo $ABC; //无输出
2. 常量名默认区分大小写,通常都写为大写
(但没找到能改变这个默认的配置项,求解)
1 <?php
define("ABC","Hello World");
echo ABC; //输出 Hello World
echo abc; //输出 abc
3. php.ini配置项指令区分大小写
如 file_uploads = 1 不能写成 File_uploads = 1
二、大小写不敏感
4. 函数名、方法名、类名 不区分大小写,但推荐使用与定义时相同的名字
<?php
function show(){
echo "Hello World";
}
show(); //输出 Hello World 推荐写法
SHOW(); //输出 Hello World
<?php
class cls{
static function func(){
echo "hello world";
}
}
Cls::FunC(); //输出hello world
5. 魔术常量不区分大小写,推荐大写
包括:__LINE__、__FILE__、__DIR__、__FUNCTION__、__CLASS__、__METHOD__、__NAMESPACE__。
<?php
echo __line__; //输出 2
echo __LINE__; //输出 3
6. NULL、TRUE、FALSE不区分大小写
<?php
$a = null;
$b = NULL;
$c = true;
$d = TRUE;
$e = false;
$f = FALSE;
var_dump($a == $b); //输出 boolean true
var_dump($c == $d); //输出 boolean true
var_dump($e == $f); //输出 boolean true
7.类型强制转换,不区分大小写,包括:
* (int),(integer) – 转换成整型
* (bool),(boolean) – 转换成布尔型
* (float),(double),(real) – 转换成浮点型
* (string) – 转换成字符串
* (array) – 转换成数组
* (object) – 转换成对象
<?php
$a=1;
var_dump($a); //输出 int 1
$b=(STRING)$a;
var_dump($b); //输出string '1' (length=1)
$c=(string)$a;
var_dump($c); //输出string '1' (length=1)
但我不是鼓励大家去用这些规则。 推荐大家始终坚持“大小写敏感”,遵循统一的代码规范。
一、大小写敏感
1. 变量名区分大小写
所有变量均区分大小写,包括普通变量以以及$_GET, $_POST, $_REQUEST, $_COOKIE, $_SESSION, $GLOBALS, $_SERVER, $_FILES, $_ENV等;
代码如下:
<?php
$abc = 'abcd';
echo $abc; //输出 'abcd'
echo $aBc; //无输出
echo $ABC; //无输出
2. 常量名默认区分大小写,通常都写为大写
(但没找到能改变这个默认的配置项,求解)
代码如下:
1 <?php
define("ABC","Hello World");
echo ABC; //输出 Hello World
echo abc; //输出 abc
3. php.ini配置项指令区分大小写
如 file_uploads = 1 不能写成 File_uploads = 1
二、大小写不敏感
4. 函数名、方法名、类名 不区分大小写,但推荐使用与定义时相同的名字
代码如下:
<?php
function show(){
echo "Hello World";
}
show(); //输出 Hello World 推荐写法
SHOW(); //输出 Hello World
代码如下:
<?php
class cls{
static function func(){
echo "hello world";
}
}
Cls::FunC(); //输出hello world
5. 魔术常量不区分大小写,推荐大写
包括:__LINE__、__FILE__、__DIR__、__FUNCTION__、__CLASS__、__METHOD__、__NAMESPACE__。
代码如下:
<?php
echo __line__; //输出 2
echo __LINE__; //输出 3
6. NULL、TRUE、FALSE不区分大小写
代码如下:
<?php
$a = null;
$b = NULL;
$c = true;
$d = TRUE;
$e = false;
$f = FALSE;
var_dump($a == $b); //输出 boolean true
var_dump($c == $d); //输出 boolean true
var_dump($e == $f); //输出 boolean true
7.类型强制转换,不区分大小写,包括:
* (int),(integer) – 转换成整型
* (bool),(boolean) – 转换成布尔型
* (float),(double),(real) – 转换成浮点型
* (string) – 转换成字符串
* (array) – 转换成数组
* (object) – 转换成对象
代码如下:
<?php
$a=1;
var_dump($a); //输出 int 1
$b=(STRING)$a;
var_dump($b); //输出string '1' (length=1)
$c=(string)$a;
var_dump($c); //输出string '1' (length=1)
[3]php读取mysql乱码,用set names XXX解决的原理分享
来源: 互联网 发布时间: 2013-11-30
先说MySQL的字符集问题。Windows下可通过修改my.ini内的
PHP代码
[mysql]
default-character-set=utf8 //客户端的默认字符集
[mysqld]
default-character-set=utf8 //服务器端默认的字符集
假设我们把两个都设为utf8,然后在MySQL Command Line Client里面输入“show variebles like“character_set_%”;”,可看到如下字符:
character_set_client latin1
character_set_connection latin1
character_set_database utf8
character_set_results latin1
character_set_server utf8
character_set_system utf8
要是我们通过采用UTF-8的PHP程序从数据库里读取数据,很有可能是一串“?????”或者是其他乱码。
解决办法是,在连接数据库之后,读取数据之前,先执行一项查询“SET NAMES UTF8”,即在PHP里为
mysql_query("SET NAMES UTF8");
//该句话一定要放在数据库服务器连接语句【$connection=mysql_connect($db_host,$db_user,$db_psw)or die("连接服务器失败");】之后
即可显示正常(只要数据库里信息的字符正常)。
到MySQL命令行输入“SET NAMES UTF8;”,然后执行“show variebles like“character_set_%”;”,发现原来为latin1的那些变量“character_set_client”、“character_set_connection”、“character_set_results”的值全部变为utf8了,原来是这3个变量在捣蛋。
查阅手册,上面那句等于:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
看看这3个变量的作用:
信息输入路径:client→connection→server;
信息输出路径:server→connection→results。
换句话说,每个路径要经过3次改变字符集编码。以出现乱码的输出为例,server里utf8的数据,传入connection转为latin1,传入results转为latin1,utf-8页面又把results转过来。如果两种字符集不兼容,比如latin1和utf8,转化过程就为不可逆的,破坏性的。
但这里要声明一点,“SET NAMES UTF8”作用只是临时的,MySQL重启后就恢复默认了。
接下来就说到MySQL在服务器上的配置问题了。岂不是我们每次对数据库读写都得加上“SET NAMESUTF8”,以保证数据传输的编码一致?能不能通过配置MySQL来达到那三个变量默认就为我们要想的字符集?手册上没说,我在网上也没找到答案。所以,从服务器配置的角度而言,是没办法省略掉那行代码的。
总结:为了让你的网页能在更多的服务器上正常地显示,还是加上“SET NAMES UTF8”吧,即使你现在没有加上这句也能正常访问。
PHP代码
代码如下:
[mysql]
default-character-set=utf8 //客户端的默认字符集
[mysqld]
default-character-set=utf8 //服务器端默认的字符集
假设我们把两个都设为utf8,然后在MySQL Command Line Client里面输入“show variebles like“character_set_%”;”,可看到如下字符:
代码如下:
character_set_client latin1
character_set_connection latin1
character_set_database utf8
character_set_results latin1
character_set_server utf8
character_set_system utf8
要是我们通过采用UTF-8的PHP程序从数据库里读取数据,很有可能是一串“?????”或者是其他乱码。
解决办法是,在连接数据库之后,读取数据之前,先执行一项查询“SET NAMES UTF8”,即在PHP里为
mysql_query("SET NAMES UTF8");
//该句话一定要放在数据库服务器连接语句【$connection=mysql_connect($db_host,$db_user,$db_psw)or die("连接服务器失败");】之后
即可显示正常(只要数据库里信息的字符正常)。
到MySQL命令行输入“SET NAMES UTF8;”,然后执行“show variebles like“character_set_%”;”,发现原来为latin1的那些变量“character_set_client”、“character_set_connection”、“character_set_results”的值全部变为utf8了,原来是这3个变量在捣蛋。
查阅手册,上面那句等于:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
看看这3个变量的作用:
信息输入路径:client→connection→server;
信息输出路径:server→connection→results。
换句话说,每个路径要经过3次改变字符集编码。以出现乱码的输出为例,server里utf8的数据,传入connection转为latin1,传入results转为latin1,utf-8页面又把results转过来。如果两种字符集不兼容,比如latin1和utf8,转化过程就为不可逆的,破坏性的。
但这里要声明一点,“SET NAMES UTF8”作用只是临时的,MySQL重启后就恢复默认了。
接下来就说到MySQL在服务器上的配置问题了。岂不是我们每次对数据库读写都得加上“SET NAMESUTF8”,以保证数据传输的编码一致?能不能通过配置MySQL来达到那三个变量默认就为我们要想的字符集?手册上没说,我在网上也没找到答案。所以,从服务器配置的角度而言,是没办法省略掉那行代码的。
总结:为了让你的网页能在更多的服务器上正常地显示,还是加上“SET NAMES UTF8”吧,即使你现在没有加上这句也能正常访问。
最新技术文章: