文章存档 » 二月 2011

可变参数个数的函数及其他

可变参数个数的函数

使用 fungetargs() 和 calluserfunc_array()

function user_func()
{
    $arg = func_get_args();
    call_user_func_array("sprintf", $arg);
}

funcgetargs函数的功能是把所有参数存到$arg变量中

calluserfunc_array函数的作用是将 $arg 中所有接收到的参数传递给指定的函数,这里是sprintf。

使用 funcgetargs() 即可定义你自己的具有可变参数个数的函数了。 而 calluserfunc_array() 函数可以很方便的用来调用具有可变参数个数的函数。(有点拗口啊)

例如:

function oot()
{
    $pa = func_get_args();
    $sql = call_user_func_array("sprintf", $pa);
    return $sql;
}

$a = 10;
$b = fingers;

echo oot("I have %d %s", $a, $b);

输出的就是 : I have 10 fingers.

浏览器缩进问题

问:为什么在div里的ul嵌套无法正常缩进?

不同浏览器对HTML各标签的样式是有默认值设定的,虽然作为开发者的我们无法控制这些默认值,但可以通过CSS Reset来重置设定,比较常见的就是

* { margin:0; padding:0 }

还有许多其他更为复杂的 CSS Reset 方案,这些CSS Reset 方案的一个共同目的就是:将不同浏览器的默认设置重置一下,从而保证所有浏览器下,样式能够全部统一。

模板技术

使用模板引擎可以使业务逻辑与显示逻辑分开,可以简单的理解模板为“PHP与HTML代码分离的方法”

让程序(PHP)与显示(HTML)分离可以使代码更清晰易懂,职责的分离使得维护变得更容易。更重要的是这样的设计可以让不懂PHP的前台美工也能修改页面。它能让程序开发者专注于资料的控制或是功能的达成;而网页设计师则可专注于网页排版,让网页看起来更具有专业感。因此,模化引擎很适合公司的Web开发团队使用,使每个人都能发挥其专长。

正则表达式

正则表达式(Regular Expression>,缩写为regexp,regex或regxp),又称正规表达式、正规表示式或常规表达式或正规化表示法或正规表示法,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容,可以很容易的选出具有某一类特点的式子。许多程序设计语言都支持利用正则表达式进行字符串操作。 

开发入门

初次面临程序开发,总会遇到各种各样的问题,这里总结一些团队中各人经历及感受,可能没有太大的通用性,仅作为一点不成熟的经验。

如何起步

除非有人手把手的教你怎么做,不然最初的问题就应该是怎样起步了。平时写个作业什么的都有固定的题目,要求通过**** 算法、理论实现 ****功能。很简单,照着做就行了。但如果在什么都不了解的情况下给出一个题目去完成,可能就要无从下手了。

各人的条件状况都不同,所以要找出一条统一的规律几乎不可能。起初怎么做,那就要靠自己一点点去摸索了。也许我喜欢逛论坛,一个帖子一 个帖子的看前辈的指点;也许我喜欢看代码,根据他人的代码一点点修改,找出其中的各种函数、语法进行研究进而做出自己的东西;也许我喜欢google,搜各种关键字……..方法不同,因人而异,但有一点不会变:不会一开始就找到适合自己的方法,不断摸索,不断前进,即使你不知道哪个适合你,那么在不断的排除不适合自己的东西后,剩下的那个,不就正是你所寻找的么。

如何找到好的文章

互联网给我们带来遍历的同时也给我们带来的大量的垃圾,如何取其精华去其糟粕就成了很重要的一点。由于我们要看的是一些技术类的文章, 这里给出几条建议,也许有些帮助:

好的资源:

  • 站点样式美观,组织有序
  • 文章层级清晰,各级标题明确
  • 有目录,导言,总结者尤佳

这些都很容易一眼看出来,如果都符合,很可能是好文章

管理好时间

Getting Things Done-GTD一种很好的行为管理方法,我们应该学会组织和规划自己的事务,管理好时间,《与时间做朋友》(by李笑来)是件不错的事情。

当你学会了规划好时间以后,你会发现自己有充足的时间去完成要做的任务和放松自己。

坚持下去

无论什么,半途而废是不可能有所作为的,就算截止日期就在今晚,就算今天已经累的不行了,那也要把它完成,即使做得很烂,但至少把它完 成了。

不怕失败

初期肯定会遇到各种各样的问题,也许是一个小小的麻烦会让你抓头发纠结一天,也许会质疑自己的付出是不是值得,不要害怕,这是每个人必须经历的步骤。坚持下去,明天的成功就是靠今天一次次的失败积累出来的。

项目开发中要注意的几点:

用户体验

想做出好的产品,用户体验应该是第一位的。目前已经有很多成功的例子摆在那里,善于学习他们的优点并加以结合自己的特点,就是我们自己的东西了。

用户体验,应该是产品的基础。

需求分析

不要想当然的去猜测需求是什么,烟囱的图纸被理解成了水井是完全不允许的事情。做事之前先确定要做的是什么,否则南辕北辙的后果只是白白浪费时间,拖延进度。

流氓程序

除非你有理由让用户一定用你的东西,否则就尽量减少或者避免在程序里添加流氓的东西,人们都希望能够自己支配所使用的东西,流氓程序无疑会令用户对你产品的印象大打折扣。至少我是不会使用那种四处弹广告强制安装程序的软件,如果有选择的话。

2011寒假总结

回想前十几年的假期,几乎都被荒废了。唯有这个寒假,真正做了点感兴趣的,有意义的事情。说到有意义,想起被小学老师逼着写“有意义”的日记,可真是无限欢乐。小毛孩子能知道什么有意义么?于是到了快要开学的时候,编10篇日记交上去。后来居然还被老师夸奖说写得有文采。红着脸低着头扣手指。

我不管别人的观点怎样,被强加的,并且我觉得无意义的事情我会尽量不去做。比如说学校布置的所谓的社会实践。至于有人说这关系到什么评比加分之类的,好像跟我也没关系。我只知道我喜欢什么,想做什么,喜欢做什么,然后朝着那个方向努力去做就是了。所以每个期末都把假期要看的书准备好,兴冲冲地带回家,开学的时候又原方不动地带回来。我把这归结为一个原因:没有计划。这个假期好得多,带回去四本,看了两本。这要归功于老段连贯的计划安排和每日的监督,在此表示十分感谢!

回顾假期所学,首先《提问的智慧》乃必读文章。经常提问的同学应该好好学习,经常被提问的同学应该会颇有感触。然后,熟悉了一下各种工具的使用方法便正式开始了寒假进阶班的课程。至于做过哪些内容,请点击任意门查看 2011寒假进阶班,这里就不一一列举了。

江湖闯名号

这里就是参加了2011寒假进阶班的所有文艺青年了。请轻拍。

小雨(7lemon)

一名涉世未深的准程序猿,码农。励志成为一名伟大黑客的人。患有轻度夜猫子综合症,习惯在夜深人静的时候胡思乱想一通。“想是一回事,想一想是另一回事。”深信唯有独立思考才能获得真知。

手套(Glove)

不成熟的乐天派,半宅男,喜欢热闹喜欢人多,经常折腾,偶尔运动。无意间与计算机打上交到并被她深深的吸引。不平于各种现状,对一些不存在的网站感兴趣。认为实践出真知,只有亲自做过才能了解真谛。希望通过自己的努力对这个世界做些改变。

咸鱼(Salted Fish)

地地道道的山西人,总是沉迷于奇奇怪怪的东西,沉迷于冥想,喜欢热闹,也喜欢安静,一个纠结的矛盾体。充满了对新鲜事物的兴趣,想要坚持自己的东西,总是不经意怀念过去。热爱运动,热爱游戏,热爱生活。相信技术能改变世界,相信技术不会欺骗。

老段(dzy0451)

喜读书,未破一卷;好哲学,不求甚解。

试炼 – 迷你WOW

这是2011年寒假进阶班的一个任务。如果你对这个任务感兴趣,欢迎参与,并与我们共享你的成果。或者你也可以报名参加我们的课程:报名:程序设计与实践2 – Web开发

一、我要下副本

考虑WOW中的一个情境,每个副本中都有几个boss,例如地狱火城墙中有巡视者加戈玛,无疤者奥摩尔,传令官瓦兹德;破碎大厅有 高阶术士奈瑟库斯,战争使者沃姆罗格,酋长卡加斯·刃拳。现在,需要构建用于存储副本信息和boss信息的数据库,假设副本和boss满足以下的条件:

  • 一个boss仅可能在一个副本中出现
  • 一个副本中可能有大量的boss,比如说100000个
  • 副本有名字,难度,简介三个属性
  • boss有名字,HP,MP,坐标四个属性

问题

  • 请给出能够存储上述信息的数据库的结构。
  • 请写一个PHP程序,显示副本及其中的boss(此程序只允许执行一次数据库查询,也就是说,你只能select一次)

格式参考如下:

地狱火城墙
巡视者加戈玛,无疤者奥摩尔,传令官瓦兹德

破碎大厅
高阶术士奈瑟库斯,战争使者沃姆罗格,酋长卡加斯·刃拳

二、我要拿装备

我们已经有了副本系统,下面我们开始下副本拿装备了。考虑,打死一个boss之后,可能出的装备有多种,例如巡视者加戈玛可能掉落的物品有:散兵的鳞片护腿,光触胸甲,奥术怒火护肩,影裂长剑,诡计护腕。看起来与问题一相似,但与问题一不同的地方在于,不同的boss可能爆出相同的装备,也就是说,一件装备可能由多个boss爆出。现在需要在问题一的数据库的基础上,对装备信息和掉落信息进行存储。

问题

  • 请在问题一的数据库的基础上进行扩展,增加对装备信息和掉落信息的存储,要求,同一个装备不能重复存储。
  • 修改问题一中的脚本,使之能够显示掉落信息和装备信息。(你依然可以仅用一条sql语句就完成这个任务,试试吧),输出的格式如下:

格式参考如下:

地狱火城墙
    巡视者加戈玛
    散兵的鳞片护腿,光触胸甲,奥术怒火护肩,影裂长剑,诡计护腕
    无疤者奥摩尔
    ……
    传令官瓦兹德
    ……

破碎大厅
    高阶术士奈瑟库斯
    ……
    战争使者沃姆罗格
    ……
    酋长卡加斯·刃拳
    ……

提示

上述数据库的结构问题,是两个非常典型的问题,你们需要了解一下数据库设计的相关知识。

  • 问题一抽象出来就是:如何存储一个实体与多个实体的对应关系(一对多)
  • 问题二抽象出来就是:如何存储多个实体与多个实体的对应关系(多对多)

至于查询和显示,则涉及到同时查询多个数据表的操作(多表联查),你也许会用到“表连接”,“笛卡尔积”之类的操作。

还想听更多的提示?先看看google怎么说。 遇到问题了想发问?先回忆一下《提问的智慧》

啊!出装备了

一个boss被消灭了,会爆出一些装备,而每个装备的爆率是各不相同的,同一个装备在不同的boss身上爆出的几率也是不同的。请扩展问题二中的数据库结构,从而可以存储装备的爆率。并撰写一个php程序,访问者可以在页面上选择要下的副本和要打的boss,击败boss之后,将根据爆率,爆出相应的装备。

PS: 你也许可以使用一些图片,并对界面稍加设计,从而使这个小游戏的可玩性更强。

四、迷你WOW

如果上面三个问题都解决了,下面你就可以考虑再增加一个用户系统,允许用户注册和登录,然后,用户登录后可以通过击杀boss获得经验,并进行升级,当然,你得存储用户的属性和boss的属性,诸如攻击力防御力之类的,在交战时你得根据这些属性判定输赢。好了,一个迷你的WOW已经出现了。邀请你的好友一起来探索艾泽拉斯吧。

项目 – Cybery Reader

这是2011年寒假进阶班的一个任务。如果你对这个任务感兴趣,欢迎参与,并与我们共享你的成果。或者你也可以报名参加我们的课程:报名:程序设计与实践2 – Web开发

接下来正式进入我们的项目开发,要开发的东西是一个RSS阅读器。名字暂定为Cybery Reader。

第一阶段的任务安排如下:

一、数据库访问的封装

分配给:手套

编写一个类 CDB ,将php的mysql库进行一下封装,提供更加简单便捷的接口。需要至少提供以下几个接口:

  • connect(host, user, pass, dbname) : 用user和pass连接到host上的dbname数据库
  • close() : 关闭数据库连接
  • fetch(table_name, field_name, value) : 从数据表tablename中取出一条记录,满足条件:字段名为fieldname的字段,其值为value
  • get(table_name, condition) :从数据表table_name中取出所有符合条件condition的记录
  • insert(table_name, data) :向数据表table_name中插入一条记录,data是一个关联数组,键名为字段名,值为字段的值
  • update(table_name, id_value, data) :更新数据表tablename中的id为idvalue的记录,data是一个关联数组,键名为字段名,值为字段的值
  • delete(table_name, id_value) :删除数据表tablename中的id为idvalue的记录
  • query(sql) :执行数据库查询sql
  • queryf(fsql, v1, v2, ...) : 具有可变参数个数的函数,类似于sprintf,fsql定义了数据格式,v1, v2等变量定义了要替换的值,然后将替换后的字符串作为数据库查询进行执行。

二、RSS Feed爬虫 (RSS Crawler)

分配给:小雨

编写一个类 RSSCrawler ,用于读取远程的RSS Feed。需要至少提供以下几个接口:

  • open(url) : 打开一个RSS Feed,返回是否打开成功
  • read_item() : 读取下一个条目,返回一个关联数组
  • valid() : 当前打开的Feed是否是一个有效的RSS Feed,返回true 或 false
  • close() : 关闭

三、PSD to HTML

分配给:咸鱼

PSD设计稿转换为一个静态HTML页面。要求如下:

  • 左右两个侧边栏的宽度固定,中间部分的宽度可变
  • 上方的“这里是提示信息”一栏,用JQuery实现向下滑动的效果
  • 页面应符合web标准,并兼容IE6+, FF, Safari, Chrome
  • 最终应产出如下文件

  • /main.html

  • /css/style.css
  • /css/images/所有样式配图
  • /images/所有内容图片

利器 – 进阶班 – 预备 – 齐

这是2011年寒假进阶班的一个任务。如果你对这个任务感兴趣,欢迎参与,并与我们共享你的成果。或者你也可以报名参加我们的课程:报名:程序设计与实践2 – Web开发

考试结束,进阶班也该开班了。工欲善其事,必先利其器。进阶班就从利器开始,所谓磨刀不误砍柴工,工具顺手可以事半功倍。

闲话少说,进入正题。

必要的阅读

阅读以下材料

使用vim

使用版本控制系统

  • 了解什么是代码版本控制
  • 了解主要的版本控制系统及各自特点
  • 详细了解git,在自己的linux上搭建一个git服务器,参照git-tutor.pdf,一步一步体验git的功能,如涉及到局域网内访问其他计算机的操作,可转换为本地操作,或使用virtual box搭建虚拟机来模拟
  • 在github上注册一个账号,尝试参与一个开源项目

使用框架

  • 了解什么是应用程序开发框架
  • 了解流行的PHP开发框架和各自的特点
  • 详细了解CodeIgniter,使用CodeIgniter构建一个应用程序,请自行命题

写点什么

做完以上任务之后,写一篇文章,体裁格式不限,字数不限,唯一的要求是:要拿得出手。别弄个像小学生日记一样的东西来敷衍。

提示

  • How to write a technical report 一文会对你有所帮助
  • 图文并茂的文章更吸引人
  • 杂乱冗长的记录尽管看起来篇幅惊人,但不见得质量过硬
  • 条理清晰的文章容易被人记住
  • 最后,别妄想出口成章,多修改几次没坏处
  • 啊,差点忘了,小心错别字

迷你WOW总结

对于PHP的初学者来说,做出一个这样简单的小程序是不会花费太多时间的。每天几个小时的时间看书写代码,一周的时间也可以完成了。没错,说的是初学者,一个没有PHP编程经验的初学者。我在写这个程序的时候,是只会一丁点PHP。做这个小项目,我觉得更多的是要对PHP有一个大概的了解,熟悉其基本的操作和应用。磨刀不误砍柴工,学会如何使用工具才能顺利地工作。

下面就这个项目说一下我从中获得的经验教训。

初学者的一页式程序

查看一下我的迷你WOW程序代码,可以看到几乎每一个页面都是一个单独的程序。程序与程序之间关联性不是很强。每个单独的PHP文本都尝试在一个文件内完成整个页面的所有功能。例如index.php,不仅含有登录功能,还含有首页动作展示的功能。更让人头疼的是,程序逻辑和页面显示相互混杂,区分起来比较困难。当初我这样写程序的时候是没意识到的,但是到了要整理代码的时候发现这个程序难以整理,倒不如重新编写一个框架简洁,逻辑清晰的程序。

写出这样的程序并不算错。因为刚刚接触这种编程模式,还对程序整体没有把握。一旦理清了自己的程序结构,对语言有了一定的了解,自然而然地就会发现自己程序的不足从而进行改进。

PHP的变量

PHP的弱类型的变量是我最喜欢的特点之一。你可能学过C/C++,Java或其他一些编程语言。他们在使用变量之前都要事先声明这个变量。刚接触PHP的时候我也是习惯性地这么做。后来发现不仅不需要这么做,如果这么做的话反而会引发一些错误。PHP变量的类型不在于你如何声明,而在于你给它赋予什么样的值。不需要事先声明,随用随写。$var有可能此刻是int型,下一刻就变成了字符串。

$key = 1;
// do something
$key = 'Oh, it's a secret';
// do something else

但是注意:虽然PHP允许这么做,为了程序的可读性,我强烈建议你不要这么做。这么做的后果是代码难以维护,前后产生歧义,让人难以理解。一个变量应该具有其唯一的意义,当然也包括类型。给变量取个有意义的名字,指定一个唯一的类型,自己看着也干净利落。

使用函数,大量的函数

这个迷你WOW一共也没使用几个函数。为了让界面和程序逻辑分离,我尝试把每个页面共用的页眉页脚分离出来。至于每个页面都有不同的标题,可以通过传递参数来解决这个问题。我确实这样做了,其中借鉴了Wordpress使用主题模板的方法。我写了header.php和footer.php两个模板,里面大部分是HTML代码,只有标题信息等变量通过PHP代码输出。然后在function.php中定义了两个函数,用require 函数来调用模板。因此便有了每段程序开头的getheader()和结尾的getfooter()。

get_header($headerData);
// do something
get_footer();

我的这个程序并没有像这段的标题所说使用大量函数,后来在做另一个项目的时候我终于尝到了使用函数的甜头。每个函数只做一件事,这会让你的程序变得清晰易懂,易于维护。而不像我的这第一个作品这样充斥着繁杂冗余的内容和让人难以理解的过程。

多读代码,读好代码

个人认为,评判好代码和坏代码的标准就是——代码是否易读。好的代码是你顺着编程者的逻辑一步一步看下去,看到程序结尾了也知道作者的意图了。而坏的代码通常是读了好几遍也不知道是什么意思,让你大叫WTF!当然,前面假设你了解作者使用的编程语言。我的迷你WOW显然是属于坏的代码范畴内的,因为连我自己都不知道如何整理它比较好了。比如data.php的输出部分就很混乱。

WordPress的代码可能算是好代码范畴内的。我在做迷你WOW的时候看过一些,很容易理解代码的意图。但是不建议刚上来就看这么复杂的代码,可以从简单的程序开始一点一点学习。毕竟如果你不想做Wordpress的开发,就没必要去深入了解其代码内容。读前辈的代码也是个不错的选择,但是要带着批判的眼光。

用心学习基础知识

做什么事都少不了基础知识。有基础才有上层建筑。这个迷你WOW彻底沦为我用来掌握基础知识的试炼程序,回头来看,还真是不怎么样。但愿以后别再写出这样糟糕的程序。如果你是一个初学者并且在看我的代码,希望不要学习这种程序结构,在其中了解一些语法规则和PHP基本方法还是可以接受的。

这样写完一个小型的比较系统的程序以后,思维自然而然地就会理顺一些。对开展下一个项目也会产生一定的信心。虽然可能掌握的东西还是很少,但学习是需要一个艰苦的过程的。不能持之以恒的话,怎么能学到真本事呢?

推荐的参考教程

之前我也一直为参考教材发愁,但是后来发现教材什么的都是浮云。PHP官方网站上提供了详细的说明文档,每个特性,方法,功能下面还有一些人提供的程序样例。这就是一个好教材啦!就像Android一样,市面上的教材基本都是开发者网站的翻译版。官方网站提供了详细的说明文档,怎么用就看你自己了。同时也推荐看一些前辈编写的经验总结,从其中去糟取精,唯一要达到的目的就是使自己进步。

浅谈程序开发过程以及代码风格

程序开发过程

程序开发过程是一个很空泛的标题,由于笔者做过的程序开发很少,在这方面根本谈不上经验,只能说是初窥门径。只是根据资料和自己的理解,就现在着手的Mini wow进行一些交流和总结。

定义:

程序开发是以下步骤的一个往复过程:编写新的源代码,测试、分析和提高新编写的代码以找出语法和语意错误。

具体步骤:

  • 明确目标:确定你的程序最终要达成什么,目标是得到什么:进行某个数据的处理?生成某种数据?等等。就Mini wow来说就是实现基本的WOW的功能,用户注册一个账户,可以进行打FB升级拿装备。这个具体功能由程序员来定。其中包括问题提出、可行性分析、需求分析和总体设计。

  • 分解步骤:对你的目标进行分解,将整个过程分成若干步骤,要达成最后的结果,首先需要完成哪一步,然后再完成哪一步,分解到每一步对你而言都比较清晰为止。比如小雨说的“可以一个界面一个界面地做,我就是这么做的。比如我现在需要一个首页,显示登录框,那我就先做个首页。然后登录完了得显示基本信息对吧,我再做信息显示。然后我要下副本,再做选择BOSS的界面…一步一步的这样”。

  • 细化最优:对于每个小步骤(已经变成相对简单的小问题),考虑有哪些实现方法,可能有多种,考虑哪种最优,对前后步骤的实现最有利。“框架都出来了,再细致地把一些东西抽出来,做成函数,让程序的逻辑更清除”。把每一步骤的逻辑用程序算法写出来,并且衔接好各个步骤,譬如采用过程控制,函数调用,等等。

  • 调试完善:整体调试程序,到正确无误位置,同时改进和重构你的程序,使得他更完善更精巧。

代码风格

代码风格的必要性就不用多说了,直接说具体的。

关于换行:

寻找最佳的断行位置

在变量申明中,根据类别分类换行,并添加注释说明。

例:

// 要计算的数值  
int num;  
// 表示影响因子  
int factor;  
// 元素所在的索引号  
int index;  
// 数据列表的总长  
int length;

在表达式中,以最能清晰的表达出逻辑为基本准则。

例:

double containerAspectRatio =  
     (double)container.ClientWidth / container.ClientHeight; 

在函数参数中,当参数数量较多,参数较长或者包含表达式的时候,这种排版比起单独写成一行更为直观醒目。

例:

Rectangle imageBounds = new Rectangle(  
    itemBounds.X + padding,  
    itemBounds.Y + padding,  
    itemBounds.Width - padding * 2,  
    itemBounds.Height - padding * 2  
); 

避免代码过于拥挤

  • 使用空行分隔代码块,逻辑块。
  • 使用空格降低代码密度

符号两侧添加空格的基本规则:

  • 单目运算符(Unary Operators)与它的操作数之间应紧密相接,不需要空格。
  • 在双目、三目运算符(Binary/Ternary Operators)的左右两侧分别添加空格,括号。
  • 括号(包括小括号、中括号与大括号)的内侧应该紧靠操作数或其他运算符,不需要添加额外的空格。
  • 不要使用连续的两个或多个空格。

其实,如果理解了这些规则,在实际书写的时候很容易遵循。对于任何一个表达式,我们先把单目运算符和括号去掉,然后在双目、三目运算符的左右两侧分别  添加一个空格,再将单目运算符和括号填回去,放在靠近自己操作数的一边即可。  关于函数调用时,要不要在函数名和其后的括号之间添加空格的问题已经讨论了很久。其实这个是一个无伤大雅的事情,无论使用何种方式,都不会对代码  的可读性产生多少实质性的影响,纯粹是各人喜好罢了。不过在这里,我建议采用Visual Studio中的默认规则:在函数调用时不添加空格,而在一些类似的带括号的语法结构中添加空格。

如何缩进

嵌套或包含关系引起的缩进,关于控制结构。尽可能的使得分支结构更清晰。

例:

if ( $a == 1 ) {  
    echo 'A was equal to 1';  
    //很容易的可以添加其他代码  
} 
elseif ( $a == 2 ) {  
    //其他操作
}

因换行而产生的缩进:我们在前面提到过,当一条语句太长而超出一定的宽度时,应该折行书写。此时,从第二行起到该语句结束之间的各行应该缩进一层,至下一条语句时再恢复原来的缩进位置。

参考

PHP include/require路径问题

include/require语句用于包含并运行指定文件。具体用法见PHP手册。

使用这两条语句时要十分注意路径的使用。一些人会习惯使用相对路径(比如我),如果不对PHP进行任何配置就直接使用相对路径,那肯定会撞南墙。例如如下目录结构:

/
/common/
/lib/

/index.php 需要require /common/header.php 则直接 require ‘common/header.php’; 即可。这种语句是不会出错的,PHP会从当前目录向下层目录寻找header.php。问题来了,如果 /common/header.php 需要require /lib/config.php 怎么办?直接的想法是这样做:

require '../lib/config.php';

我第一次就是怎么做的,然后执行脚本的时候PHP抛出了找不到这个文件的错误。解决办法有二(或更多):

方法一:使用绝对路径

require dirname(__FILE__).'/../lib/config.php';

使用 dirname(__FILE__) 将获得当前文件所在的绝对路径。这种方法也即使用绝对路径来指定文件位置。

方法二:设定include_path

指定include_path。参考自PHP文档,includepath string:指定一组目录用于 require(),include() 和 fopenwithpath() 函数来寻找文件。格式和系统的 PATH 环境变量类似:一组目录的列表,在 UNIX 下用冒号分隔,在 Windows 下用分号分隔。 既然这样,只要修改PHP配置文件,将脚本所在的根目录加入到includepath就可以使用相对目录了。例如项目脚本根目录在 /var/www/project 则编辑PHP配置文件,在include_path中加入 /var/www/project 。这样,我们首先想到的相对目录办法就可以使用了。

实际上在执行include / require等语句的时候,PHP会首先查找include_path中指定的目录内是否有对应文件,如果没有则将path置成当前文件所在的目录,认为当前目录为根目录并不支持相对路径。除非使用绝对路径,否则不能查找同级其他目录的文件。