PHP技术

需求是把数组按照树形结构排列,假设数据是在数据库中的。

最简单的思路或者说常规的思路就是递归算法了。递归算法是比较快的和准确的,但是有一个问题就是会比较浪费不必要的资源,递归算法执行的过程中会开启N个 函数入口,也就是函数需要一直保存状态等待起递归的运算结果。例如这个树形有 5层*60行,则在递归算法中浪费的运算至少60次,并且保持5个函数一直是运算中状态,不合理的是同样要做60+次的数据库查询,因为不管其有没有子类,算法执行过程中都需要去重复执行递归运算,事实上实际执行过程中不止这个数。

可以写个简单的例子来测试递归算法调用函数的次数。

/* 先假设我的数据是这样子的
array(
      array(id=>1,pid=>0),
      array(id=>2,pid=>0),
      array(id=>3,pid=>2),
      array(id=>4,pid=>0),
      array(id=>5,pid=>3), 
      array(id=>6,pid=>1),
      array(id=>7,pid=>1),
      array(id=>8,pid=>6),
      array(id=>9,pid=>7),
      array(id=>10,pid=>9)
); */
$db = new MysqlDb();
$num = 0;
function treeArray($pid) {
  global $db, $num;
  $num++;
  $data = $db -> getAll("SELECT * FROM test_a WHERE pid = ".$pid); //返回一个二维数组
  $result = array();
  foreach($data as $val) {
    $val['child'] = treeArray($val['id']);
    $result[] = $val;
  }
  return $result;
}

print_r(treeArray(0));  //树形的结果
var_dump($num);         //11

然后我们系统越作越大了,数据库资源紧张了,我们要求在不改变数据库结构的同时尽可能的减少数据库的操作。那么这样做就需要我们有一算法来给你的数据排序了。

$num = 0;
function treeArray() {
  global $num, $db;
  $data = $db -> getALl("SELECT * FROM test_a WHERE 1");
  $result = array();
  foreach($data as $val) {
    $num++;
    if($val['pid'] == 0) {
      $val['child'] = getChild($val['id'], $data);
      $result[] = $val;
    }
  }
  return $result;
}

function getChild($pid, $data) {
  global $num;
  $result = array();
  foreach($data as $val) {
    $num++;
    if($val['pid'] == $pid) {
      $val['child'] = getChild($val['id'], $data);
      $result[] = $val;
    }
  }
  return $result;
}   
print_r(treeArray());
var_dump($num);        //110

好了,我们最起码实现了不用多次请求数据库了,不过在作数组遍历的时候我们做了很多次运算~然后我们的系统功能模块越来越多,其中树形结构数据这一块的调用也特别多,程序执行速度越来越不进人意了。我们则需要设计一个速度更快,消耗资源更少的算法。这里我用了php里的变量引用,其它语言里肯定也有这种引用方式,有些类似于C语言的指针。

function treeArray() {
  global $db;
  $data = $db -> getAll("SELECT * FROM test_a WHERE 1");
  $result = array();
  //定义索引数组,用于记录节点在目标数组的位置  
  $I = array();

  foreach($data as $val) {
    if($val['pid'] == 0) {
      $i = count($result);
      $result[$i] = $val;
      $I[$val['id']] = & $result[$i];
    } else {
      $i = count($I[$val['pid']]['child']);
      $I[$val['pid']]['child'][$i] = $val;
      $I[$val['id']] = & $I[$val['pid']]['child'][$i];
    }
  }

  return $result;
}

print_r(treeArray());

申明:算法不是我原创的,希望抛砖引玉出更好的算法。查看源代码:http://www.greatmoo.com/untest/samples/sort/

感觉程序设计语言本身其实要学的东西很少,真正要学的是算法和数据结构,准备采购《算法导论》。

meiking   2009-04-08 13:07:20 阅读:343  评论:0  引用:0
〖摘要:〗

configure: error: Unable to find libgd.(a|so)

如果使用的是ubuntu或debian就很简单了,直接sudo apt-get install apache2 libapache2-mod-php5 php5 php5-gd 就基本上搞定,但是用源代码安装还是很麻烦~

wget http://www.boutell.com/gd/http/gd-2.0.11.tar.gz
tar zxvf gd-2.0.11.tar.gz
cd gd-2.0.11
sudo ./configure --prefix=/usr/local/gd2
sudo make
sudo make install

再php:~/:./configure  …… --with-gd=/usr/local/gd2  ……


以下是转载的,而且都是基于yum install或者apt-get的。

1) Configure: error: xml2-config not found. Please check your libxml2 installation.

Solutions :

Quote:
#yum install libxml2 libxml2-devel (For Redhat & Fedora)

# aptitude install libxml2-dev      (For ubuntu)

2) Checking for pkg-config… /usr/bin/pkg-config
configure: error: Cannot find OpenSSL’s <evp.h>

Solutions :

Quote:
#yum install openssl openssl-devel

3) Configure: error: Please reinstall the BZip2 distribution

Solutions :

Quote:
# yum install bzip2 bzip2-devel

4) Configure: error: Please reinstall the libcurl distribution -
easy.h should be in <curl-dir>/include/curl/

Solutions :

Quote:
# yum install curl curl-devel   (For Redhat & Fedora)

# install libcurl4-gnutls-dev    (For Ubuntu)

5) Configure: error: libjpeg.(also) not found.

Solutions :

Quote:
# yum install libjpeg libjpeg-devel

6) Configure: error: libpng.(also) not found.

Solutions :

Quote:
# yum install libpng libpng-devel

继续阅读其余的  4368 字
meiking   2009-04-01 12:35:47 阅读:1843  评论:0  引用:0

昨天拿到一个完整的静态页面带有很多产品图,不过这些产品图片的特别大,是真实的产品大图。使用firebugs加载了一下发现整个页面加载完后居然有8MB多。当然这种网页是不被我认可直接放在互联网上的。

于是就用正则找出了网页中所有图片,取得其“height”和“width”值,然后使用PHP的GD库按照“img”标签中的高和宽重新生成实际显示在网页中的图片。使用这个方法重新生成的新网页加载完后只有400KB左右,而且显示效果上没有明显的差别,还算满意。

方法很简单,不过需要去温习一下正则表达式,正则表达式这种东西一般不用,学会了也很容易忘记,比较郁闷~,所以要养成写笔记的习惯。

<?php
function getImages() {
        $files = file("templates/default/index.html");
        $i = 1;
        $result = array();
        foreach($files as $file) {
                $tmp_str = preg_match("/img.+src=[\"|\'](.+)[\"|\'].+width=[\"|\'](.+)[\"|\'].+height=[\"|\'](.+)[\"|\']\ /i", $file, $regs);
                if($tmp_str) {
                        $tmp_r = array();
                        $tmp_r = array("path" => $regs[1],
                                        "width" => $regs[2],
                                        "height" => $regs[3]
                                      );
                        if(file_exists($tmp_r['path']) ) {
                                $tmp_r['size'] = filesize($tmp_r['path']);
                                $result[] = $tmp_r;
                        } else {
                        }
                }
        }
        return $result;
}

$result = getImages();

require ("cls_image.php");
$img = new cls_image();

foreach($result as $i) {
        $path = $img->make_thumb($i['path'], $i['width'], $i['height'], $i['path']);
        if($path) echo "<img src='".$path."' />";
}
?>

其中 cls_images.php文件太长,请从这里查看:http://www.greatmoo.com/untest/samples/cls_image.php

meiking   2009-03-30 14:04:30 阅读:62  评论:0  引用:0

php的empty函数和isset函数是用来判断变量的,并且只能用来判断变量,不能用来判断常量,例如下面的例子就会输出语法错误。

<?PHP
define("DEFINED_VAR", 1);
//var_dump(empty(DEFINED_VAR));
var_dump(empty("0"));
var_dump(isset(DEFINED_VAR));
?>

和朋友聊php变量类型的时候提总结了一些东西,php的变量类型很灵活,可以简单的看作没有变量类型。但是也别小看其变量类型了,其实php是有完整的变量类型的。看下面的例子。

<?PHP
var_dump(0 == "");
var_dump(0 == NULL);
var_dump(0 == false);
var_dump(false == NULL);
var_dump("" == false);
var_dump(1 == true);

var_dump(0 === "");
var_dump(0 === NULL);
var_dump(0 === false);
var_dump(false === NULL);
var_dump("" === false);
var_dump(1 === true);

var_dump(1 === 1);&nbsp;&nbsp; //当要作类型的判断的时候需要用“===”或者“!==”。
var_dump(true === true);
var_dump(NULL === NULL);
?>

查看实例结果:http://www.greatmoo.com/untest/samples/variable2.php

另外null在程序中是未定义的变量。

<?PHP
$var = NULL;
var_dump(isset($var)); //return false
?>
meiking   2009-03-30 14:02:41 阅读:190  评论:0  引用:0

作了这么多年的PHP开发居然一直没有用debug工具,说来真的很丢人,于是最近学习了一下。

利用Xdebug+VIM配置的新的测试环境,能跟踪代码执行过程以及每一步的执行结果。Zend Eclipse的debug功能更为强大,配置也简单,不过公司的机器用了Xdebug,两者只能选其一~

 

Ubuntu+PHP+Apache+Xdebug+vim

由于ubuntu和debian都有“apt-get"这个工具,在ubuntu下配置起来就很简单了,分为A&B两步。

A、安装PHP模块和Xdebug模块
注意:这里假设用户已经通过apt-get install 过了apache2 和 php5了。

sudo apt-get install php5-dev php5-cli
#其中php5-dev为了安装xdebug所以必须安装。

sudo apt-get install php5-xsl
#Xinc需要xsl extension

sudo pecl install xdebug
#编译成功说明已经安装完成
#如果上面的安装没有执行,那么应该是缺少perl,那么执行 sudo apt-get install perl

#编辑/etc/php5/apache/php.ini和/etc/php5/cli/php.ini加入
#zend_extension=”/usr/lib/php5/20060613+lfs/xdebug.so”。


sudo /etc/init.d/apache2 restart
#重启apache

B、安装VIM 插件
如果没有安装vim请现安装vim: sudo apt-get install vim

cd ~/
#进入用户根目录

wget http://www.greatmoo.com/xdebug-plugin.tar.gz
#下载xdebug的vim插件

tar zxvf xdebug-plugin.tar.gz
#解压

mkdir .vim
mv plugin/ .vim/
#建立vim用户配置目录,并且安装该plugin

C、使用

  1. 在你要debug的地址中加上参数“XDEBUG_SESSION_START=1“
  2. 进入vi,按F5开启监控端口
  3. 操作网页
  4. 进入VI的界面,然后就有提示你该怎么做了。
meiking   2009-03-09 18:04:10 阅读:234  评论:0  引用:0

昨天一个客户的网站做正式推广了,访问量一下从2位数上升到5位数,接近两万,在线用户4千多,然后就发现网站特别慢了。服务器配置是双至强(Intel Xeon 5110 1.6G)CPU,3G的内存,50MB独享的带宽,装得是win2003系统(劝其用linux,说linux网管太贵-_-!)。在线4千多的时候系统消耗大概是700+MB,10%的CPU消耗,但是带宽才使用了5MB,很奇怪,拼命的催我帮解决一下。哎~书到用时方恨少啊,不过我猜可能是程序上的问题比较大一些,不过看到资源的消耗似乎就不像是程序的事情了,估计还是apache设置的问题。

昨晚上只做了下面的修改:

  • 利用apache自带的工具修改log存储按照日期方式存储(log数据一天写了400+MB):
    # CustomLog "logs/access.log" common
    CustomLog "|bin/rotatelogs.exe logs/access-%Y-%m-%d.log 86400" common #86400是一天的秒数
  • 屏蔽winnt_accept警告:
    EnableMMAP off
    EnableSendfile off
    Win32DisableAcceptEx

早晨起来发现其实效果不大,但是却没有一个很好的监控方法。好在这个不是业务范围之内的东西~,不过能解决当然做好了,只能硬着头皮补充apache知识了。

 

Edited at 8-4 21:26

问题找到了,无心插柳柳成阴,居然不是apache的问题,冤枉我补充了些apache知识,错误如下,对win2003毫无兴趣,就不刨根问底了。


meiking   2008-08-04 09:29:57 阅读:117  评论:0  引用:0
现在拿PHP做网站感觉速度确实快,这样工作的时候我经常能空出一部份时间来学习。PHP v5对象在一年前我才了解的,其实时间也挺长的,了解了后就在项目中实验性的用了些,但当时因为团队开发,我这套方法很不受其它队员的欢迎,因为真的比较 费事,而没有习惯面象对象方法的人会觉得很麻烦多此一举。其实想想也是,PHP本来就是适合做快速短频的开发,要的是开发效率,如果需要用到这些对象和以 系统运行效率为主,那么可能就不需要我们这些PHP程序员了。不过我看完这遍"高级PHP v5对象"文章时我就非常搞不懂,既然有那么优秀的JAVA面象对象语言,那么还需要费这么大劲来研究PHP的面向对象呢?难道上帝为了让我们这些PHP 程序员能继续活下去?那么真的太谢谢上帝了。本身我对上帝不太了解,长什么样都不知道,一点都不熟,人家还那么照顾我,可能PHP程序员普遍长的帅吧。

文章不是我写的,去看原文吧:高级 PHP V5 对象

  PHP 对于我来说我非常喜欢的,你可以随心所俗的编写自己的程序,也不用花太多时间去研究架构,大多数情况根本不用去考虑数据类型,不用考虑内存和数据库连接的 问题。特别是要实验个算法时用它实现可以免去例如数据类型,编译等麻烦的步骤。我认识的仅有的几位编程高手都会PHP,他们写例子和做测试经常用到 PHP。不过这些优点也是PHP缺点所有,不用考虑数据类型肯定会有程序漏洞,没有架构维护性和护展性就差,没有处理内存和连接的问题肯定就无法合理的分 配有限的内存。也就是说PHP能做的东西比较有限,但一般情况下,起码对于现在互联网上70%以上网站来说是够用了。

meiking   2008-04-10 01:59:45 阅读:39  评论:0  引用:0
〖摘要:〗
记得在卓达大学学习PHP时问过余博(师父)一个问题: PHP中是否支持一个类同时继承两个类。 因为当时有一个类里需要用到其它两个类的方法,就想继承两个类,但似乎没有这样的写法。。 后来随着技术的提升,这种问题在工作在也轻松的解决掉了,就没有浪费时间在研究这个问题上了。

PHP5出来有些日子了,一直觉得不会有大的变化就赖得去看,今天一仔细一看,大吃一惊~


Matt Zandstra, 开发人员和作家

2005 年 6 月 20 日

本文描述 PHP V5 中对象和类的基础知识,从最基本的概念一直讲到继承,主要针对经验丰富的面向对象程序员和尚未接触过对象的读者。

作为 PHP 程序员,您肯定知道变量和函数。但类和对象可能就是另一回事。不定义单个类,就可以创建完美的系统。但即使您决定在自己的代码中不使用面向对象的编程,您 仍可能需要了解面向对象的编程。例如,如果使用第三方库,比如通过 PHP Extension and Application Repository (PEAR) 可以使用的库,您将发现自己在实例化对象和调用方法。

什么是类和对象?

简单地说, 是一个由变量和方法组成的独立块或束。这些组件通常结合实现单个责任或一组责任。在本文中,您将创建一个类,该类收集了用于查询和填充由项和值组成的词典的方法。

类可以直接用作组织数据和功能的简单方法,就像一组函数和变量一样。但使用类可以忽略它的存在。类可用于在内存中生成多个实例。这样的实例叫做对象。每个对象可以访问一组相同的函数(在面向对象上下文中叫做方法)和变量(叫做特性实例变量),但每个变量的实际值在每个对象中是不同的。

考虑角色扮演游戏中的一个单元——比如坦克。类可能为坦克设置一组变量:防御和进攻能力,范围,健康状况,等等。该类也可能定义一组函数,其中包括 move()attack()。当系统包含一个坦克类时,该类可用于生成数十个或数百个坦克对象,每个对象都潜在地具有自己的健康状况或范围特征。因此,类是用于生成对象的蓝图或模板。

理解类和对象最简单的方法可能就是创建一些类和对象。








第一个类

可以用 class 关键字创建类。最简单的情况是,类由关键字类、名称和代码块组成:


class Dictionary {

}


类名可以包含字母、数字和下划线字符的任何组合,但不能以数字打头。

上例中的 Dictionary 类尽管用处有限,但完全合法。那么如何使用该类来创建一些对象呢?


$obj1 = new Dictionary();
$obj2 = new Dictionary();
$obj3 = new Dictionary();


至少在形式上,实例化对象与调用函数相似。对于函数调用,必须提供圆括号。与函数一样,一些类需要您为其传递参数。您还必须使用 new 关键字。这就告诉 PHP 引擎您希望实例化一个新对象。然后,返回的对象可以存储在一个变量中以供将来使用。








属性

在类的主体中,可以声明叫做属性的特殊变量。在 PHP V4 中,属性必须用关键字 var 调用。这仍是合法的语法,但主要是为了向后兼容。在 PHP V5 中,属性必须声明为 public、private 或 protected。可以在 继续阅读其余的  36133 字

meiking   2008-04-10 01:31:08 阅读:26  评论:0  引用:0
Copyright@2008 powered by YuLog