php无限级评论嵌套实例介绍

 更新时间:2016年11月25日 15:45  点击:2165
无限级分类,让人兴奋但却又让人有些不知所措的数据结构。让人兴奋,是因为这种结构实在是太实用太方便了;让人不知所措,是因为这种结构的前台数据结构展现往往会在递归的时候浪费非常多珍贵的性能资源。

我在设计BB的过程中,也一直在思考是否可以不通过递归来实现无限级分类的结构展现和父子结构查找,因为如果不对这里的算法进行优化后果可能是致命的!试想一下,一篇文章如果评论数为300,按正常的递归算法,至少就得查询数据库301次,而且还是在没有任何嵌套的情况下,如果有过一两级嵌套或者评论数过1000,那数据库不是直接宕掉?
而实际上,PHP强大的数组处理能力已经能帮助我们快速方便的解决这个问题。下图为一个无限级分类的

数据库结构:

 IDparentID newsID commts
 108文章ID为8的评论
 21 8对ID为1的评论的回复
 328对ID为2的评论的回复

要在前台嵌套式的展现文章编号8的评论,其实我们只用查询一次数据库,即“SELECT * FROM TABLE WHERE newsID=8”,而把后期的递归工作交给强大的PHP数组来完成。这里可能涉及的问题就是数组的结构关系的重组,即将所有停留在一级分类上的评论全部放到自己的parentID下,形成children项。
下面将BBComment类中这块的代码粘贴出来,希望与大家分享下我的思路,也希望大家能够提出更好更有效率的算法。

 代码如下 复制代码


/** 
 * 按ID条件从评论数组中递归查找 
 * 
 */ 
function getCommentsFromAryById($commtAry, $id)  
{  
    if ( !is_array($commtAry) ) return FALSE;  
    foreach($commtAry as $key=>$value) {  
        if ( $value['id'] == $id ) return $value;  
        if ( isset($value['children']) && is_array($children) ) $this->getCommentsFormAryById($value['children'], $id);  
    }  
}  
/** 
 * 追加 子评论 到 主评论 中,并形成children子项 
 * 
 * @param array $commtAry 原评论数据引用 
 * @param int $parentId 主评论ID 
 * @param array $childrenAry 子评论的值 
 */ 
function addChildenToCommentsAry($commtAry, $parentId, $childrenAry)  
{  
    if ( !is_array($commtAry) ) return FALSE;  
 
    foreach($commtAry as $key=>$value) {  
        if ( $value['id'] == $parentId ) {  
            $commtAry[$key]['children'][] = $childrenAry;  
            return TRUE;  
        }  
        if ( isset($value['children']) ) $this->addChildenToCommentsAry($commtAry[$key]['children'], $parentId, $childrenAry);  
    }  
}  
    $result = $this->BBDM->select($table, $column, $condition, 0, 1000);  
 
    /* 开始进行嵌套评论结构重组 */ 
    array_shift($result);  
    $count = count($result);  
    $i     = 0;  
    while( $i<$count ) {  
        if ( '0' != $result[$i]['parentId'] ) {  
            $this->addChildenToCommentsAry($result, $result[$i]['parentId'], $result[$i]);  
            unset($result[$i]);  
        }  
        $i++;  
    }  
    $result = array_values($result);  
    /* 重组结束 */ 

PHP一维数组的排序可以用sort(),asort(),arsort()等函数,但是PHP二维数组的排序需要自定义。

自定义:

 代码如下 复制代码

function array_sort($arr,$keys,$type='asc'){ //2维数组排序
 $keysvalue = $new_array = array();
 foreach ($arr as $k=>$v){
  $keysvalue[$k] = $v[$keys];
 }
 if($type == 'asc'){
  asort($keysvalue);
 }else{
  arsort($keysvalue);
 }
 reset($keysvalue);
 foreach ($keysvalue as $k=>$v){
  $new_array[$k] = $arr[$k];
 }
 return $new_array;
}

最近在做一个数据分析系统,需要用到各种排序,下面是一段排序:

 代码如下 复制代码

//$re 为数据来源,二维数组

$re = $this->array_sort($re,'LV','desc');//排序
 foreach($re as $key=>$val){
  foreach ($val as $key2=>$val2){
   if($key2=="uid"){
   $count[] = $val2;//获取创建角色总数
   $lv[$val2][]=$re[$key]['LV'];//获取所有角色等级 
   }
    
  }
 }
 $count = array_count_values($count); 
 foreach($count as $key=>$val){
  M()->query("update mj_ad_count set create_juese = create_juese+".$val." where suid =".$key);
  echo M()->getLastSql();  
 }
 foreach($lv as $key =>$val){//等级排查找出最大值后写入统计
  foreach ($val as $key2=> $val2){
   if($key2==0){
    //$ls[$key][] = $val2;
    M()->query("update mj_ad_count set juese_leave = ".$val2." where suid =".$key);
    echo M()->getLastSql(); 
   }   
  }
 }

在php中Session经常用来验证用户注册或登录之后的验证了,下面我来总结session变量的一些常用实例与用法介绍。

当您运行一个应用程序时,您会打开它,做些更改,然后关闭它。这很像一次会话。计算机清楚你是谁。它知道你何时启动应用程序,并在何时终止。但是在因特网上,存在一个问题:服务器不知道你是谁以及你做什么,这是由于 HTTP 地址不能维持状态。
通过在服务器上存储用户信息以便随后使用,PHP session 解决了这个问题(比如用户名称、购买商品等)。不过,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久储存信息,可以把数据存储在数据库中。

把手册抄一下,然后每个都试试然后写出来,方便自己查阅滴,谁让咱刚学呢。Session大概有12个函数分别是:

session_start: 初始 session。
session_destroy: 结束 session。
session_unset: 释放session内存。
session_name: 存取目前 session 名称。
session_module_name: 存取目前 session 模块。
session_save_path: 存取目前 session 路径。
session_id: 存取目前 session 代号。
session_register: 注册新的变量。
session_unregister: 删除已注册变量。
session_is_registered: 检查变量是否注册。
session_decode: Session 资料解码。
session_encode: Session 资料编码。

还有个全局变量就是:$_SESSION


在您把用户信息存储到 PHP session 中之前,首先必须启动会话。
注释:session_start() 函数必须位于 标签之前:

 代码如下 复制代码
<?php session_start(); ?>
 
<html>
<body>
 
</body>
</html>

 

存储 Session 变量

 代码如下 复制代码
<?php
session_start();
// store session data
$_SESSION['views']=1;
?>
 
<html>
<body>
 
<?php
//retrieve session data
echo "Pageviews=". $_SESSION['views'];
?>
 
</body>
</html>

 

终结 Session
unset() 函数用于释放指定的 session 变量:

 代码如下 复制代码
<?php
unset($_SESSION['views']);
?>

 

您也可以通过 session_destroy() 函数彻底终结 session:

 代码如下 复制代码
<?php
session_destroy();
?>

 

 代码如下 复制代码

<?php
session_start();
switch ( $_GET['action'] ){
case "loginif";
//登陆验证,假定session储存的秘密应该等于123才为正确
if ($_SESSION['pass']=="123"){echo "密码正确 您可以执行注销";}else{echo "密码错误,您可以重新登陆";}
break;
case "logout";
//注销登陆
session_unset();
session_destroy();
echo "注销成功!可以判断一下密码是否正确来看看是不是成功注销";
break;
case "login";
//写入session以供验证,
$pass="123";//密码
$_SESSION['pass']=$pass;
echo "写入登陆密码了 去判断密码成功与否吧。";
break;
}
?>
<p>假定本页名为temp.php </p>
<p><a href="temp.php?action=login">用户进行登陆post,程序处理写入session</a></p>
<p><a href="temp.php?action=loginif">判断用户密码是否正确</a></p>
<p><a href="temp.php?action=logout">登陆成功的用户注销登陆</a></p>

我总结了一下php中session的用法。


(一)开始session
  在每一次使用session之前,都要加上这一句:“session_start();”。顾名思义,这个函数的作用就是开始使用session。
(二)注册session
  首先要建立一个global(注意,一定要定义为global,不然在其它页面用不了)数组,如$login,其中$login['name']="Victor",$login['pwd']="111111",然后调用函数“session_register(login);”,session就成功注册了。
(三)使用session里面的变量
  和注册session类似,都要先建立一个global数组,然后就和使用一般数组一样了。
(四)判断session是否注册
  很简单,用“if (session_is_registered(login))”判断就可以了。
(五)卸载session
  也很简单,“session_unregister(login);”就可以了。
  注意:在进行(二)(三)(四)(五)之前一定要先进行(一)。


下面给出一个例子:

index.htm

 代码如下 复制代码

<html>
<head>
<title>测试</title>
</head>
<body>
<FORM METHOD=POST ACTION="login.php">
用户名:<INPUT TYPE="text" NAME="name"><br/>
密码:<INPUT TYPE="password" name="pwd"><br/>
<INPUT TYPE="submit" value="提交">
</FORM>
</body>
</html>


login.php

 代码如下 复制代码

<?php
global $login;
if ($_POST['name']!="Victor" || $_POST['pwd']!="111111")
{
        echo "登陆失败";
        echo "请<a href=index.htm>返回</a>";
        exit;
}
$login = array('name'=>$_POST['name'],
                           'pwd'=>$_POST['pwd']);
session_start();
session_register(login);
echo "<a href=info.php>查看信息</a><br/>";
echo "<a href=logout.php>退出登陆</a><br/>";
?>


info.php

 代码如下 复制代码

<?php
session_start();
if (session_is_registered(login))
{
        global $login;
        echo "hello,".$login['name']."<br/>";
        echo "<a href=logout.php>退出登陆</a><br/>";
}
else
{
        echo "非法操作<br/>";
        exit;
}
?>


logout.php

 代码如下 复制代码


<?php
session_start();
session_unregister(login);
header("location:index.htm");
?>

本文章来给大家总结一个关于php写入、删除、复制文件及创建修改时间例子,有碰到此类的同学可进入参考。

例子1:

读写文件

 代码如下 复制代码

<?php
$filename = 'txt/write.txt';
//定义要写入的内容
$content = "李先生 36 山东nr王先生 49 湖南nr孙先生 40 河北";
//使用is_writable()函数确定文件存在并且可写
if(is_writable($filename)){
//把文件写入到文件尾,应选择操作标记a
if(false == ($handle = fopen($filename, 'a'))){
echo "文件 $filename 打开失败";
exit();
}
//将$content写入打开的文件
if(fwrite($handle, $content) === false){
echo "写入文件 $filename 失败";
exit();
}
echo "写入文件 $filename 成功";
//关闭句柄
fclose($handle);
}else{
echo "文件 $filename 没有写权限";
}
?>

php写入文件例子2:

 代码如下 复制代码

<?php
$filename = "Test\file.txt";
$file = fopen($filename, "w");      //以写模式打开文件
fwrite($file, "Hello, world!n");      //写入第一行
fwrite($file, "This is a test!n");      //写入第二行
fclose($file);         //关闭文件
?>

删除文件:

 代码如下 复制代码

<?php
$filename = "Test\file.txt";
unlink($filename);    //删除文件
?>

复制文件:

 代码如下 复制代码

<?php
$filename1 = "Test\file.txt";
$filename2 = "Test\file.bak";
copy($filename1, $filename2);      //复制文件
?>

文件创建、修改、访问时间

实例

 代码如下 复制代码

< ?php
$a=filectime("log.txt");
echo "创建时间:".date("Y-m-d H:i:s",$a)."
";
$a=filemtime("log.txt");
echo "修改时间:".date("Y-m-d H:i:s",$a)."
";
$a=fileatime("log.txt");
echo "访问时间:".date("Y-m-d",$a)."
";
?>

PHP fileatime()函数
定义和用法
fileatime() 函数返回指定文件的上次访问时间。

该函数返回文件上次被访问的时间。如果出错则返回 false。时间以 Unix 时间戳的方式返回。

语法
fileatime(filename)  filename 必需。规定要检查的文件。

提示和注释
提示:本函数的结果会被缓存。请使用 clearstatcache() 来清除缓存。

注释:文件的 atime 应该在不论何时读取了该文件中的数据块时被更改。当一个应用程序定期访问大量文件或目录时很影响性能。有些 Unix 文件系统可以在加载时关闭 atime 的更新以提高这类程序的性能。USENET 新闻组假脱机是一个常见的例子。在这种文件系统下,本函数没有用处

ip地址转成十进制数是根据的公式算出来的:74×256^3+30×256^2+10×256+243 = 1243482867或者说分别将IP地址的四位数字化成十六进制,将得到的十六进制去掉\"小数点\"后再化为十进制即可。

PHP 中如何将ip地址转成十进制数呢?现在PHP中有很多时候都会用到ip地址,但是这个ip地址获取的时候都不是10进制的。那么PHP中如何将ip地址转成十进制数就是我们比较头疼的事情了,下面两种方法是我整理处理来相对比较简单的IP地址转成十进制数的方法。希望能对大家有所帮助。

方法一:

 代码如下 复制代码

public function ipToLong(){
        $ip = $_SERVER['REMOTE_ADDR'];
        $ip = explode('.', $ip);
        $ip = array_reverse($ip);//数组反转
        $r = 0;
        for($i=0,$j=count($ip); $i<$j; $i++){
            $r += $ip[$i] * pow(256, $i);
        }
        $r = sprintf("%u", $r);
        echo $r;
}

方法二:

 代码如下 复制代码

public function ipToLong(){
        $ip = $_SERVER['REMOTE_ADDR'];
        $ip = explode('.',$ip);
        $r = ($ip[0] << 24) | ($ip[1] << 16) | ($ip[2] << 8) | $ip[3];
        if($r < 0) $r += 4294967296;
        echo $r ;
}

两个结果在本地服务器中的结果都是3232235877,运用的ip是192.168.1.101。我们用ping 192.168.1.101 和 ping 3232235877来进行检测,看是否一样。

可能有些朋友不知道mysql与php中都提供了IP转换十进制数函数

MySQL 提供了INET_ATON 和 INET_NTOA 两个函数来进行地址和整数之间的转换。

1. IP 由点分格式,转换为数字格式。

 代码如下 复制代码

mysql> select inet_aton('127.0.0.1');
+------------------------+
| inet_aton('127.0.0.1') |
+------------------------+
| 2130706433 |
+------------------------+
1 row in set (0.00 sec)

2. IP 由数字格式转换为点分格式。

 代码如下 复制代码

mysql> select inet_ntoa(2130706433);
+-----------------------+
| inet_ntoa(2130706433) |
+-----------------------+
| 127.0.0.1 |
+-----------------------+
1 row in set (0.00 sec)


php可直接使用ip2long函数

 代码如下 复制代码


echo ip2long('192.168.1.38');
输出:3232235814

[!--infotagslink--]

相关文章

  • Spring AOP 对象内部方法间的嵌套调用方式

    这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • vue.js Router中嵌套路由的实用示例

    这篇文章主要给大家介绍了关于vue.js Router中嵌套路由的相关资料,所谓嵌套路由就是路由里面嵌套他的子路由,文章通过示例代码介绍的非常详细,需要的朋友可以参考下...2021-06-27
  • python 爬取京东指定商品评论并进行情感分析

    本文主要讲述了利用Python网络爬虫对指定京东商城中指定商品下的用户评论进行爬取,对数据预处理操作后进行文本情感分析,感兴趣的朋友可以了解下...2021-05-28
  • Antd的Table组件嵌套Table以及选择框联动操作

    这篇文章主要介绍了Antd的Table组件嵌套Table以及选择框联动操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-25
  • 快速理解MySQL中主键与外键的实例教程

    主键与外键的关系,通俗点儿讲,我现在有一个论坛,有两张表,一张是主贴 thread,一张是回帖 reply先说说主键,主键是表里面唯一识别记录的字段,一般是帖子id,体现在访问的时候,例如是 thread.php&#63;id=1 表示我要访问的是帖子...2015-11-24
  • yii添删改查实例

    一、数据访问对象 (DAO)YiiDAO 基于 PHP Data Objects (PDO) 构建。它是一个为众多流行的DBMS提供统一数据访问的扩展,这些 DBMS 包括MySQL, PostgreSQL 等等。因此,要使用 Yii DAO,PDO 扩展和特定的 PDO 数据库驱动(例如...2015-11-24
  • c# 接口使用实例

    这篇文章主要介绍了c#接口使用的实例,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-17
  • 在vue中实现嵌套页面(iframe)

    这篇文章主要介绍了在vue中实现嵌套页面(iframe),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-31
  • springboot +redis 实现点赞、浏览、收藏、评论等数量的增减操作

    这篇文章主要介绍了springboot +redis 实现点赞、浏览、收藏、评论等数量的增减操作,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-15
  • python使用for...else跳出双层嵌套循环的方法实例

    这篇文章主要给大家介绍了关于python使用for...else跳出双层嵌套循环的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用python具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-05-18
  • vue前端开发层次嵌套组件的通信详解

    vue通过provide & inject两个关键字完成父组件向子孙组件直接传值,很像子类能够使用父类的属性一样方便。provide & inject一般用于多层之间的传值,两层之间还是使用props进行...2021-10-10
  • Python爬虫实战之爬取携程评论

    今天带大家爬取携程评论练练手,文中有非常详细的代码示例,对正在学习python的小伙伴们很有帮助,需要的朋友可以参考下...2021-06-02
  • 帝国CMS调用最新最多评论文章

    /*解决代码高亮太长不换行*/ .syntaxhighlighter{word-break:break-all;} uParse('#newstext', {rootPath: '/e/extend/ueditor/'}) 用灵动标签调用最新最多评论文章: [...2016-08-27
  • C#中的IEnumerable简介及简单实现实例

    这篇文章主要介绍了C#中的IEnumerable简介及简单实现实例,本文讲解了IEnumerable一些知识并给出了一个简单的实现,需要的朋友可以参考下...2020-06-25
  • Java优化for循环嵌套的高效率方法

    这篇文章主要介绍了Java优化for循环嵌套的高效率方法,帮助大家更好的提升java程序性能,感兴趣的朋友可以了解下...2020-09-14
  • Window.Open打开窗体和if嵌套代码

    这篇文章主要介绍了Window.Open打开窗体和if嵌套代码的相关资料,需要的朋友可以参考下...2016-04-18
  • php socket讲解与实例

    在这一章里你将了解到迷人而又让人容易糊涂的套接字(Sockets)。Sockets在PHP中是没有充分利用的功能。今天你将看到产生一个能使用客户端连接的服务器,并在客户端使用sock...2016-11-25
  • C++内核对象封装单实例启动程序的类

    这篇文章主要介绍了利用C++内核对象封装的类,程序只能运行单个实例,可防止多次启动,大家参考使用吧...2020-04-25
  • php 中缓冲输出实例代码

    ob_start([string output_callback])- 打开输出缓冲区   所有的输出信息不在直接发送到浏览器,而是保存在输出缓冲区里面,可选得回调函数用于处理输出结果信息。 ob...2016-11-25