PHP轮询排序实现逐条循环滚动置顶
什么轮询排序
打个比方:对于很多拥有广告客户的网站来说,如果有很多客户在网站上投放广告,同一个价格下,怎么对客户广告进行排序呢?特别公平的排序方法就是每一个客户广告轮流进行置顶,每隔一定的时间轮流进行位置排序,不断的逐条循环滚动置顶,让每一个客户都有同等的机会显示在第一位。这种排序方式叫做轮询排序。
实现方法
如何实现这样的轮询排序条循环滚动置顶功能呢?可以使用PHP强大的代码来写。PHP代码如下:
<?php
date_default_timezone_set( 'prc' );
// 数组数据:
$list = range( 1 , 100 );
// 按时间轮流排序:对list列表每5秒进行一次位置轮询排序,每次排1条。
$list = dataPollingInterval( $list , '5 sec' , 1 ) ;
// 输出排序好的数据 如果除5于1 输出换行
$out = '';
foreach ( $list as $k=>$v ) {
$out .= '<li>'.$v.'</li>';
// if ( $k % 5 == 1 ) {
// $out .= '<br /><br />';
// }
}
echo '<ul id="pins" class="upgun">';print_r( $out );echo '</ul>';
/*
* @名称: 对数组每隔一定的时间(自设定时间)来轮流进行位置排序,轮询的排行榜。
精确到指定的秒 或 分钟 或 小时 或 天 ,对数据列表进行轮排。
* @参数: (array)$list 顺序数组,传入需要进行轮排的数组;
* @参数: (time string)$polling_time 间隔时间 , 轮排间隔的时间。可以是:数字 + 秒、分、时、天(英文单词);
* @参数: (int)$polling_number 每次轮流换排多少条数据;
* @返回值: array | false , 如果排序成功返回array,否则异常情况返回false.
* 代码来源:学做网站论坛 https://www.xuewangzhan.net/
*
*/
function dataPollingInterval( $list , $polling_time='10 second minute hour day' , $polling_number=1 ) {
// 规划轮询间隔时间的参数:
$interval = false;
// 判断$polling_time 的类型是 秒、分、小时、天 中的哪1种。
$arg = array(
's'=>1 , // 秒
'm'=>60 , // 分= 60 sec
'h' =>3600 , // 时= 3600 sec
'd' => 86400 , // 天= 86400 sec
);
// 判断间隔时间的类型,并计算间隔时间
foreach ( $arg as $k => $v ) {
if ( false !== stripos( $polling_time , $k ) ) { //查找$k第一次出现位置
$interval = intval( $polling_time ) * $v;//获取变量的整数值;
break;
}
}
// 判断间隔时间
if( !is_int( $interval ) ){//检测变量是否是整数
return false;
}
// 从今年开始的秒数
$this_year_begin_second = strtotime( date( 'Y-01-01 01:00:01' , time() ) );//将英文文本日期时间解析为 Unix 时间戳
// 当前时间与开始时间的间隔秒数 - 今年开始的秒数,得到今年到目前为止的秒数。time()返回当前时间的 Unix 时间戳
$polling_time = time() - $this_year_begin_second;
// 从今年到目前为止的秒数,计算得到当前轮数
$len = count( $list ); // 总长度返回数组中元素的数目
$start_index = intval( $polling_time / $interval );//获取变量的整数值 (时长除间隔时间,得到次数)
$start_index = $polling_number * $start_index % $len; // 轮排数量 * 轮数 , 取余 总数量。
$res = array( );
// 将轮数 指向到数组的索引,然后从这个索引开始接着往下循环遍历。
for ( $i=0; $i < $len ; ++$i ) {
$index = $i + $start_index; // 索引的变化是根据时间来变
// 当遍历索引超过数组的最大下标时,
if ( $index >= $len ) {
$index = $index - $len ;
}
$res[] = $list[ $index ]; // 存入结果
}
return $res;
}
?>
以上是一种通过PHP编程的PHP轮询排序方法,这种轮询排序是一种隐藏式循环,变化过程不会显示普通用户,用户显示刷新页面才可以看到变化。
如果想让普通用户看到这个轮询循环的过程,可以对上面的代码进行改造,代码如下:
<?php
date_default_timezone_set( 'prc' );
if ( isset( $_GET['go'] ) ) {
// 数组数据:
$list = range( 1 , 100 );
// 按时间轮流排序:对list列表每5秒进行一次位置轮询排序,每次排10条。
$list = dataPollingInterval( $list , '2 sec' , 3 ) ;
// 输出排序好的数据
$out = '';
foreach ( $list as $k=>$v ) {
$out .= ' '.$v;
if ( $k % 20 == 19 ) {
$out .= '<br /><br />';
}
}
echo '<pre>';print_r( $out );echo '</pre>';
exit;
}
/*
* @名称: 对数组每隔一定的时间(自设定时间)来轮流进行位置排序,轮询的排行榜。
精确到指定的秒 或 分钟 或 小时 或 天 ,对数据列表进行轮排。
* @参数: (array)$list 顺序数组,传入需要进行轮排的数组;
* @参数: (time string)$polling_time 间隔时间 , 轮排间隔的时间。可以是:数字 + 秒、分、时、天(英文单词);
* @参数: (int)$polling_number 每次轮流换排多少条数据;
* @返回值: array | false , 如果排序成功返回array,否则异常情况返回false.
*/
function dataPollingInterval( $list , $polling_time='10 second minute hour day' , $polling_number=1 ) {
// 规划轮询间隔时间的参数:
$interval = false;
// 判断$polling_time 的类型是 秒、分、小时、天 中的哪1种。
$arg = array(
's'=>1 , // 秒
'm'=>60 , // 分= 60 sec
'h' =>3600 , // 时= 3600 sec
'd' => 86400 , // 天= 86400 sec
);
// 判断间隔时间的类型,并计算间隔时间
foreach ( $arg as $k => $v ) {
if ( false !== stripos( $polling_time , $k ) ) {
$interval = intval( $polling_time ) * $v;
break;
}
}
// 判断间隔时间
if( !is_int( $interval ) ){
return false;
}
// 从今年开始的秒数
$this_year_begin_second = strtotime( date( 'Y-01-01 01:00:01' , time() ) );
// 当前秒数 - 今年开始的秒数,得到今年到目前为止的秒数。
$polling_time = time() - $this_year_begin_second;
// 从今年到目前为止的秒数,计算得到当前轮数
$len = count( $list ); // 总长度
$start_index = intval( $polling_time / $interval );
$start_index = $polling_number * $start_index % $len; // 轮排数量 * 轮数 , 取余 总数量。
$res = array( );
// 将轮数 指向到数组的索引,然后从这个索引开始接着往下循环遍历。
for ( $i=0; $i < $len ; ++$i ) {
$index = $i + $start_index; // 索引的变化是根据时间来变
// 当遍历索引超过数组的最大下标时,
if ( $index >= $len ) {
$index = $index - $len ;
}
$res[] = $list[ $index ]; // 存入结果
}
return $res;
}
?>
<!DOCTYPE>
<html>
<head>
<title>php轮流排序</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="containner" class=""></div>
</body>
</html>
<script type="text/javascript">
<!--
var $ = function ( id ) {
return typeof id == "string" ? document.getElementById( id ) : id;
}
// ajax方法:ajax( url , function(){ ... } , if_post_param );
function ajax(B,A){this.bindFunction=function(E,D){return function(){return E.apply(D,[D])}};this.stateChange=function(D){if(this.request.readyState==4){this.callbackFunction(this.request.responseText)}};this.getRequest=function(){if(window.ActiveXObject){return new ActiveXObject("Microsoft.XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}return false};this.postBody=(arguments[2]||"");this.callbackFunction=A;this.url=B;this.request=this.getRequest();if(this.request){var C=this.request;C.onreadystatechange=this.bindFunction(this.stateChange,this);if(this.postBody!==""){C.open("POST",B,true);C.setRequestHeader("X-Requested-With","XMLHttpRequest");C.setRequestHeader("Content-type","application/x-www-form-urlencoded");C.setRequestHeader("Connection","close")}else{C.open("GET",B,true)}C.send(this.postBody)}};
window.setInterval(
function ( ) {
ajax(
'?go=1' ,
function ( text ) {
$( "containner" ).innerHTML = text;
}
);
} ,
);
//-->
</script>
通过使用以上代码结合while循环写入数组的方式,就可以实现动态的调用了。