首页 > 编程技术 > php

php 无限分类实现原理详解

发布时间:2016-11-25 15:47

在php中无限分类是我们在实际开发中经常用到的一种数据结构,一般我们称之为树形结构,像我网站的分类php教程有php入门,正则等等分类,这种是二级不是无限级了,如果是无限级就可以在子类下加子类了。

我们先来看我实现无限分类的具体过程。

题设:类似淘宝的商品分类,可以在任意分类设置其子类。
 

一、创建`type`数据表

 代码如下 复制代码

`id` 自增长

`fid` int(11) 默认(0) ,父节点id

`name` varchar(50),分类名称

CREATE TABLE `type` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fid` int(11) NOT NULL DEFAULT '0',
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

二、添加

我们先添加几个顶级分类

 代码如下 复制代码

INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '0', '手机');
INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '0', '电脑');
INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '0', '鞋子');
INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '0', '衣服');这里fid=0是代表顶级分类

 

接着我们为{电脑}添加几个个子分类

 代码如下 复制代码

INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '2', '台式'), (NULL, '2', '笔记本');这里fid=2,

2这个id是分类{电脑}的id,如果是添加{鞋子}的子分类则fid=3

同理我们为{笔记本}添加子分类则fid=6

 代码如下 复制代码

INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '6', 'ausu'), (NULL, '6', 'hp');

三、删除

如果我们想删除{笔记本}这个分类,很简单

DELETE FROM `type` WHERE `id`=6{笔记本}的子分类我们也要记得做相应的处理

 代码如下 复制代码


function del($fid) {
    $sql="SELECT * FROM `type` WHERE `fid`=$fid";
    $rs=mysql_query($sql);
   
    for ($i = 0; $i < count($rs); $i++) {
        $sql="DELETE FROM `type` WHERE `id`={$rs[$i]['id']}";
        mysql_query($sql);
       
        del($rs['id']);//递归
    }
}

del(6);//执行操作这里你也许你会疑惑为什么那么麻烦用递归,而不是直接这样删除

DELETE FROM `type` WHERE `fid`=6这样我们不就可以直接删除{ausu}、{hp}?但是假设{ausu}有一个子分类{a1},{a1}也有一个子分类{a2},如果不用递归我们就无法彻底删除数据。

 

三、查找

1.查找{电脑}的子分类

SELECT * FROM `type` WHERE `fid`=22.查找{电脑}的所有子分类

 代码如下 复制代码


function sel($fid) {
    $sql="SELECT * FROM `type` WHERE `fid`=$fid";
    $rs=mysql_query($sql);
   
    for ($i = 0; $i < count($rs); $i++) {
        echo $rs[$i]['name'];
       
        sel($rs[$i]['id']);//递归
    }
}

sel(2);

四、实际数据应用

在数据表添加一个字段`tid`,字段值为记录所属分类`type`表的id。必须是id不能是name,因为name的值可能会改变。

例如查询属于{电脑}分类的商品

 代码如下 复制代码

SELECT * FROM `goods` WHERE `tid`=2


下面再看个实例,直接操作数组

 

 代码如下 复制代码

<?php
$rows = array(
    array(
        'id' => 1,
        'name' => 'dev',
        'parentid' => 0
    ),
    array(
        'id' => 2,
        'name' => 'php',
        'parentid' => 1
    ),
    array(
        'id' => 3,
        'name' => 'smarty',
        'parentid' => 2
    ),
    array(
        'id' => 4,
        'name' => 'life',
        'parentid' => 0
    ),
    array(
        'id' => 5,
        'name' => 'pdo',
        'parentid' => 2
    ),
    array(
        'id' => 6,
        'name' => 'pdo-mysql',
        'parentid' => 5
    ),
    array(
        'id' => 7,
        'name' => 'java',
        'parentid' => 1
    )
);

// 72648
// 84072

function findChild(&$arr,$id){
 
    $childs=array();
     foreach ($arr as $k => $v){
         if($v['parentid']== $id){
              $childs[]=$v;
  
         }
       
    }
     
    return $childs;
   
   
}
function build_tree($root_id){
    global $rows;
    $childs=findChild($rows,$root_id);
    if(empty($childs)){
        return null;
    }
   foreach ($childs as $k => $v){
       $rescurTree=build_tree($v[id]);
       if( null !=   $rescurTree){
       $childs[$k]['childs']=$rescurTree;
       }
   }
    return $childs;
}

 
$tree=build_tree(0);

echo memory_get_usage();

print_r($tree);


?>

我自己用的可以做那种下拉效果并带有级数的效果

 代码如下 复制代码


function dafenglei_select($m,$id, $fenlei ){
 global $menu;
 $n = str_pad('',$m,'-',STR_PAD_RIGHT);
 $n = str_replace("-","&nbsp;&nbsp;&nbsp;",$n);
 for($i=0;$i<count($fenlei);$i++){
 
  if($fenlei[$i]['classid']==$id){
     $menu .= "<option value="".$fenlei[$i]['id']."">".$n."|—".$fenlei[$i]['name']."</option>n";
   }
   $this->dafenglei_select($m+1,$fenlei[$i]['id'], $fenlei );
  }
 }
 return $menu;
}

dafenglei_select(0,0, $fenlei );

$fenlei  无限分类数组 $id是选择从哪个分类开始 写0代表顶级开始分,只要把数组放进去就可以分了

在学习时我们经常会被老师拿几个数字来让大家进行各种排序,下面我来给各位同学介绍一下PHP冒泡排序算法,大家可直接合去给你老题师哈。

排序实现过程如下:
49   38   65   97   76   13   27
38   49   65 97   76   13   27               比较第1个和第2个数,小的放前边,大的放后边 38   49   65   97   76   13   27               比较第2个和第3个数,小的放前边,大的放后边 38   49   65   97   76   13   27               比较第3个和第4个数,小的放前边,大的放后边 38   49   65   76   97   13   27               比较第4个和第5个数,小的放前边,大的放后边 38   49   65   76   13   97   27               比较第5个和第6个数,小的放前边,大的放后边 38   49   65   76   13   27   97               比较第6个和第7个数,小的放前边,大的放后边 至此,第一趟比较结束,得到以下排序: 38   49   65   76   13   27   97  
然后按照第一趟排序的方法继续比较,直到完成排序。

列1

 代码如下 复制代码

$arr = array(345,4,17,6,52,16,58,69,32,8,234);
for($i=1;$i<count($arr);$i++){
for($j=count($arr)-1;$j>=$i;$j--){
if($arr[$j]<$arr[$j-1]){
$temp = $arr[$j-1];
$arr[$j-1] = $arr[$j];
$arr[$j] = $temp;
}
}
}

列2

 代码如下 复制代码

/**
 * php冒泡排序算法的实现
 * @param array $array 一维数组
 * @return array 排序过后的数组
 */
function bsort(array $array){
    $count = count($array);
    if($count == 0){
        return array();
    }elseif($count == 1){
        return $array;
    }elseif($count > 1){
        for($i=0;$i<$count;$i++){
            for($j=$count-1;$j>$i;$j--){
                if($array[$j]<$array[$j-1]){
                    $temp = $array[$j];
                    $array[$j] = $array[$j-1];
                    $array[$j-1] = $temp;
                }
            }
        }
        return $array;
    }else{
        return false;
    }
}

$arr = array(56,2,5,78,110,36,52,77,89,3,10);
print_r(bsort($arr));

本文章来给大家介绍一些常用见的php 统计计算中文汉字字数代码,有需要了解的朋友可进入参考。

用ASCII码判断。

 代码如下 复制代码
<?
$str="abcdefg中华人民共和国中国人民解放军中国共产党中国人民";
$num=strlen($str); //$num字串长度。
echo $num."<br>";
for($i=0;$i<$num;$i++)
if(ord(substr($str,$i,1))>0xa0) $j++;
echo $j/2; //$j/2 汉字数。
?>


应该这样剥除所有字母数字和标点,空格。

代码:

 代码如下 复制代码

<?php

$testStr = '我没有告诉你,你就千万不要乱guess, 这样可不good!';
$testStr = eregi_replace("[[:alnum:]]|[[:punct:]]|[[:space:]]",'',$testStr);
echo($testStr);
echo ('字符串中所有中文字数为:'.mb_strlen($testStr));
?>


#计算中英文混合字符串的长度

 代码如下 复制代码

function ccStrLen($str)
{
$ccLen=0;
$ascLen=strlen($str);
$ind=0;
$hasCC=ereg("[xA1-xFE]",$str); #判断是否有汉字
$hasAsc=ereg("[x01-xA0]",$str); #判断是否有ASCII字符
if($hasCC && !$hasAsc) #只有汉字的情况
return strlen($str)/2;
if(!$hasCC && $hasAsc) #只有Ascii字符的情况
return strlen($str);
for($ind=0;$ind<$ascLen;$ind++)
{
if(ord(substr($str,$ind,1))>0xa0)
{
$ccLen++;
$ind++;
}
else
{
$ccLen++;
}
}
return $ccLen;
}
function ccStrLeft($str,$len) #从左边截取中英文混合字符串
{
$ascLen=strlen($str); if($ascLen<=$len) return $str;
$hasCC=ereg("[xA1-xFE]",$str); #同上
$hasAsc=ereg("[x01-xA0]",$str);
if(!$hasCC) return substr($str,0,$len);
if(!$hasAsc)
if($len & 0x01) #如果长度是奇数
return substr($str,0,$len+$len-2);
else
return substr($str,0,$len+$len);
$cind=0;$flag=0;
while($cind<$ascLen)
{
if(ord(substr($str,$cind,1))<0xA1) $flag++;
$cind++;
}
if($flag & 0x01)
return substr($str,0,$len);
else
return substr($str,0,$len-1);
}

有时我们会碰到上传文件时发现太大的上传不了,下面我来给大家介绍修改PHP上传文件大小限制的方法有需要了解的朋友可参考。

php.ini中进入修改

file_uploads = on ;是否允许通过HTTP上传文件的开关。默认为ON即是开
upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就会用系统默认的临时文件夹
upload_max_filesize = 8m ;望文生意,即允许上传文件大小的最大值。默认为2M
post_max_size = 8m ;指通过表单POST给PHP的所能接收的最大值,包括表单里的所有值。默认为8M


利用.htaccess文件

htaccess里写入

php_value post_max_size 12m

php_value upload_max_filesize 12m

php_value max_execution_time 120

php_value max_input_time 240


但在php中,默认的该页最久执行时间为 30 秒.就是说超过30秒,该脚本就停止执行

这就导致出现 无法打开网页的情况.这时我们可以修改 max_execution_time

在php.ini里查找

max_execution_time

默认是30秒.改为

max_execution_time = 0

0表示没有限制

另一种方法是可以在php程序中加入

set_time_limit();

来设定页面最久执行时间.

set_time_limit(0);//0表示没有限制


另外要说明的是,post_max_size 大于 upload_max_filesize 为佳.

 下面,我们简要介绍一下PHP文件上传涉及到的一些参数:

·  file_uploads  是否允许通过HTTP上传文件的开关,默认为ON,即是:允许upload_tmp_dir   用来说明PHP上传的文件放置的临时目录,要想上传文件,得保证服务器没有关闭临时文件和有对文件夹的写权限,如果未指定则PHP使用系统默认值。upload_max_filesize  允许上传文件大小的最大值,默认为2Mpost_max_size 控制在采用POST方法进行一次表单提交中PHP所能够接收的最大数据量。如果希望使用PHP文件上传功能,则需要将此值改为比upload_max_filesize要大。

· max_input_time  以秒为单位对通过POST、GET以及PUT方式接收数据时间进行限制。如果应用程序所运行环境处在低速链路上,则需要增加此值以适应接收数据所需的更多时间。
·  memory_limit  为了避免正在运行的脚本大量使用系统可用内存,PHP允许定义内存使用限额。通过memory_limit变量来指定单个脚本程序可以使用的最大内存容量变量memory_limit的值应当适当大于post_max_size的值 。

·  max_execution_time 设置了在强制终止脚本前PHP等待脚本执行完毕的时间,此时间以秒计算。当脚本进入了一个无限循环状态时此变量非常有用。然而,当存在一个需要很长时间完成的合法活动时(例如上传大型文件),这项功能也会导致操作失败。在这样的情况下必须考虑将此变量值增加,以避免PHP在脚本正在执行某些重要过程的时候将脚本关闭

有朋友问php与mysql有没有办法把日期转时间戳或把指定日期转换成时间戳呢,其实这个是有并且还非常的简单,下面我来给大家介绍介绍。

一、在MySQL中完成
  
这种方式在MySQL查询语句中转换,优点是不占用PHP解析器的解析时间,速度快,缺点是只能用在数据库查询中,有局限性。
1. UNIX时间戳转换为日期用函数: FROM_UNIXTIME()
一般形式:

 代码如下 复制代码
select FROM_UNIXTIME(1156219870);

2. 日期转换为UNIX时间戳用函数: UNIX_TIMESTAMP()
一般形式:

 代码如下 复制代码
Select UNIX_TIMESTAMP('2006-11-04 12:23:00′);

举例:mysql查询当天的记录数:

 代码如下 复制代码

$sql=”select * from message Where DATE_FORMAT(FROM_UNIXTIME(chattime),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d') order by id desc”;

当然大家也可以选择在PHP中进行转换,下面说说在PHP中转换。

二、在PHP中完成
  
这种方式在PHP程序中完成转换,优点是无论是不是数据库中查询获得的数据都能转换,转换范围不受限制,缺点是占用PHP解析器的解析时间,速度相对慢。
1. UNIX时间戳转换为日期用函数: date()
一般形式:date('Y-m-d H:i:s', 1156219870);
2. 日期转换为UNIX时间戳用函数:strtotime()
一般形式:


strtotime('2010-03-24 08:15:42');

 代码如下 复制代码

<?php
class SaonekController extends Controller {

 public function indexAction(){
/*时间戳转换成日期不用说了
但是日期要转成时间戳的话就要用到strtotime()
*/
         $time = time();//时间戳
   $nowtime = date('Y-m-d H:i:s',$time);//生成带格式的日期
   $oldtime = '2010-11-10 22:19:21';
         $catime = strtotime($oldtime);//日期转换为时间戳
   $nowtimes = date('Y-m-d H:i:s',$catime);//时间戳又转回日期了
   echo  $nowtimes;
 }
}

?>


要求只能在白天8:00-20:00发送短信,怎么样获得到每天的这段时间区间?

如下代码:

 代码如下 复制代码


<?
$y=date("Y",time());
$m=date("m",time());
$d=date("d",time());
$start_time = mktime(9, 0, 0, $m, $d ,$y);
$end_time = mktime(19, 0, 0, $m, $d ,$y);
$time = time();
if($time >= $start_time && $time <= $end_time)
{
// do something....
}
?>

一些你不知道的用法

 代码如下 复制代码

<?php

# on 2/8/2010
date('m/d/y', strtotime('first day')); # 02/01/10
date('m/d/y', strtotime('last day')); # 02/28/10
date('m/d/y', strtotime('last day next month')); # 03/31/10
date('m/d/y', strtotime('last day last month')); # 01/31/10
date('m/d/y', strtotime('2009-12 last day')); # 12/31/09 - this doesn't work if you reverse the order of the year and month
date('m/d/y', strtotime('2009-03 last day')); # 03/31/09
date('m/d/y', strtotime('2009-03')); # 03/01/09
date('m/d/y', strtotime('last day of march 2009')); # 03/31/09
date('m/d/y', strtotime('last day of march')); # 03/31/10
?>


注意:php5.1以上时间戳会与实际时间相差8小时,解决办法如下

1、最简单的方法就是不要用php5.1以上的版本--显然这是不可取的方法!!!

2、修改php.ini。打开php.ini查找date.timezone 去掉前面的分号= 后面加Asia/Shanghai,重启apache服务器即可--缺点就是如果程序
放到别人的服务器上,不能修改php.ini,那就奈何不得了。

3、在程序中添加时间的初始化的语句的 即:“date_default_timezone_set("Asia/Shanghai"); ”这个可以由程序员任意设置,我的推
荐。
时区标识符,大陆内地可用的值是:PRC,Asia/Chongqing ,Asia/Shanghai ,Asia/Urumqi (依次为中国,重庆,上海,乌鲁木齐) ,Etc/GMT-8,Asia/Harbin
港台地区可用:Asia/Macao ,Asia/Hong_Kong ,Asia/Taipei (依次为澳门,香港,台北)
还有新加坡:Asia/Singapore

 

标签:[!--infotagslink--]

您可能感兴趣的文章: