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
然后我们系统越作越大了,数据库资源紧张了,我们要求在不改变数据库结构的同时尽可能的减少数据库的操作。那么这样做就需要我们有一算法来给你的数据排序了。
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语言的指针。
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/
感觉程序设计语言本身其实要学的东西很少,真正要学的是算法和数据结构,准备采购《算法导论》。
configure: error: Unable to find libgd.(a|so)
如果使用的是ubuntu或debian就很简单了,直接sudo apt-get install apache2 libapache2-mod-php5 php5 php5-gd 就基本上搞定,但是用源代码安装还是很麻烦~
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 :
| #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 :
| #yum install openssl openssl-devel |
3) Configure: error: Please reinstall the BZip2 distribution
Solutions :
| # yum install bzip2 bzip2-devel |
4) Configure: error: Please reinstall the libcurl distribution -
easy.h should be in <curl-dir>/include/curl/
Solutions :
| # yum install curl curl-devel (For Redhat & Fedora)
# install libcurl4-gnutls-dev (For Ubuntu) |
5) Configure: error: libjpeg.(also) not found.
Solutions :
| # yum install libjpeg libjpeg-devel |
6) Configure: error: libpng.(also) not found.
Solutions :
| # yum install libpng libpng-devel |
继续阅读其余的 4368 字
昨天拿到一个完整的静态页面带有很多产品图,不过这些产品图片的特别大,是真实的产品大图。使用firebugs加载了一下发现整个页面加载完后居然有8MB多。当然这种网页是不被我认可直接放在互联网上的。
于是就用正则找出了网页中所有图片,取得其“height”和“width”值,然后使用PHP的GD库按照“img”标签中的高和宽重新生成实际显示在网页中的图片。使用这个方法重新生成的新网页加载完后只有400KB左右,而且显示效果上没有明显的差别,还算满意。
方法很简单,不过需要去温习一下正则表达式,正则表达式这种东西一般不用,学会了也很容易忘记,比较郁闷~,所以要养成写笔记的习惯。
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
php的empty函数和isset函数是用来判断变量的,并且只能用来判断变量,不能用来判断常量,例如下面的例子就会输出语法错误。
define("DEFINED_VAR", 1);
//var_dump(empty(DEFINED_VAR));
var_dump(empty("0"));
var_dump(isset(DEFINED_VAR));
?>
和朋友聊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); //当要作类型的判断的时候需要用“===”或者“!==”。
var_dump(true === true);
var_dump(NULL === NULL);
?>
查看实例结果:http://www.greatmoo.com/untest/samples/variable2.php
另外null在程序中是未定义的变量。
$var = NULL;
var_dump(isset($var)); //return false
?>
作了这么多年的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了。
#其中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
#进入用户根目录
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、使用
- 在你要debug的地址中加上参数“XDEBUG_SESSION_START=1“
- 进入vi,按F5开启监控端口
- 操作网页
- 进入VI的界面,然后就有提示你该怎么做了。
昨天一个客户的网站做正式推广了,访问量一下从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毫无兴趣,就不刨根问底了。
文章不是我写的,去看原文吧:高级 PHP V5 对象
PHP 对于我来说我非常喜欢的,你可以随心所俗的编写自己的程序,也不用花太多时间去研究架构,大多数情况根本不用去考虑数据类型,不用考虑内存和数据库连接的 问题。特别是要实验个算法时用它实现可以免去例如数据类型,编译等麻烦的步骤。我认识的仅有的几位编程高手都会PHP,他们写例子和做测试经常用到 PHP。不过这些优点也是PHP缺点所有,不用考虑数据类型肯定会有程序漏洞,没有架构维护性和护展性就差,没有处理内存和连接的问题肯定就无法合理的分 配有限的内存。也就是说PHP能做的东西比较有限,但一般情况下,起码对于现在互联网上70%以上网站来说是够用了。
PHP5出来有些日子了,一直觉得不会有大的变化就赖得去看,今天一仔细一看,大吃一惊~
2005 年 6 月 20 日
本文描述 PHP V5 中对象和类的基础知识,从最基本的概念一直讲到继承,主要针对经验丰富的面向对象程序员和尚未接触过对象的读者。
作为 PHP 程序员,您肯定知道变量和函数。但类和对象可能就是另一回事。不定义单个类,就可以创建完美的系统。但即使您决定在自己的代码中不使用面向对象的编程,您 仍可能需要了解面向对象的编程。例如,如果使用第三方库,比如通过 PHP Extension and Application Repository (PEAR) 可以使用的库,您将发现自己在实例化对象和调用方法。
什么是类和对象?
简单地说,类 是一个由变量和方法组成的独立块或束。这些组件通常结合实现单个责任或一组责任。在本文中,您将创建一个类,该类收集了用于查询和填充由项和值组成的词典的方法。
类可以直接用作组织数据和功能的简单方法,就像一组函数和变量一样。但使用类可以忽略它的存在。类可用于在内存中生成多个实例。这样的实例叫做对象。每个对象可以访问一组相同的函数(在面向对象上下文中叫做方法)和变量(叫做特性或实例变量),但每个变量的实际值在每个对象中是不同的。
考虑角色扮演游戏中的一个单元——比如坦克。类可能为坦克设置一组变量:防御和进攻能力,范围,健康状况,等等。该类也可能定义一组函数,其中包括 move() 和 attack()。当系统包含一个坦克类时,该类可用于生成数十个或数百个坦克对象,每个对象都潜在地具有自己的健康状况或范围特征。因此,类是用于生成对象的蓝图或模板。
理解类和对象最简单的方法可能就是创建一些类和对象。
第一个类
可以用 class 关键字创建类。最简单的情况是,类由关键字类、名称和代码块组成:
|
类名可以包含字母、数字和下划线字符的任何组合,但不能以数字打头。
上例中的 Dictionary 类尽管用处有限,但完全合法。那么如何使用该类来创建一些对象呢?
|
至少在形式上,实例化对象与调用函数相似。对于函数调用,必须提供圆括号。与函数一样,一些类需要您为其传递参数。您还必须使用 new 关键字。这就告诉 PHP 引擎您希望实例化一个新对象。然后,返回的对象可以存储在一个变量中以供将来使用。
属性
在类的主体中,可以声明叫做属性的特殊变量。在 PHP V4 中,属性必须用关键字 var 调用。这仍是合法的语法,但主要是为了向后兼容。在 PHP V5 中,属性必须声明为 public、private 或 protected。可以在 继续阅读其余的 36133 字
