CharInt (PHP) 让数据库字符串按自然数排列 PHP MySQL

qiukong 11天前 106

【警告】

试验性脚本,请勿用于正式场合!

Experimental function, DO NOT use in formal occasions!

也请高手协助审阅查错,特此感谢!


【代码】

本函数最大处理14位自然数,即最大99999999999999,超过不会被转换。

function charint_encode($var){
return preg_replace_callback('/\d+/',function($row){
return (strlen($row['0'])>14)?$row['0']:sprintf('<%\'_9s>',base_convert($row['0'],10,36));
},htmlspecialchars($var));
}
function charint_decode($var){
return htmlspecialchars_decode(preg_replace_callback('/\<(.*?)\>/',function($row){
return base_convert($row['1'],36,10);
},$var));
}

Github:https://github.com/qiukong/CharInt


【说明】

在使用百度网盘等应用时经常发现一个现象,文件名不按自然数排列,例如:

小说1.txt

小说10.txt

小说3.txt

小说400.txt

小说5.txt

这是因为数据库的varchar字段在unicode排序规则下是按照从前向后进行排序的。而很多字符串并不是纯自然数,不能使用int列排序,这就造成了很大的麻烦。于是我写了这个函数,利用自然数转换和补位等方式,实现了字符串的转换和还原,让其在数据库内按自然数顺序。


【缺点】

1. 不支持非阿拉伯数字(一、二、壹、八、捌、⑧、Ⅷ、Eight)的转换,这个如果真有需要可以先给字符串创建别名,再把别名内非阿拉伯数字转换为阿拉伯数字(不是很好实现,但网上有些示例),然后再用我这个函数排序。

2. 支持的自然数有位数限制,因为我用32位PHP7写的函数,在我这测试没问题就发出来了。如果想扩充位数可以考虑自己修改,不过我觉得作为数字序列来说14位已经足够了。(身份证那类固定位数的本身就可以按顺序排列)

3. 有些数字占用了比之前还多的字符位数。这个没办法,想实现自然数排序只能采用补位。不过我已经用36进制编码压缩了,相比也不会增加太多数据库占用。


【演示】

转换前的排序:

SELECT * FROM `test_char` ORDER BY `old` LIMIT 50

转换后的排序:

SELECT * FROM `test_conv` ORDER BY `new` LIMIT 50

这排序是不是就顺溜了?


最新回复 (0)
返回
发新帖