此书无中文版,但是写的极好!本来想翻译的,可是时间不允许了。

http://www.amazon.com/Advanced-PHP-Programming-George-Schlossnagle/dp/0672325616/ref=pd_rhf_dp_p_t_1

约定:加粗字体表示章节,由于时间关系解释性的说明全部省略。

《高级 PHP程序设计》

简介

PHP在企业级开发

一个编程语言满足下面6方面才能满足关键的商业应用:

快速原型设计和实施

现代编程范式的支持

可伸缩性

高性能

互操作性

可扩展性

平台和版本

本书主要是针对php5,更主要是使你的代码更快,更敏捷,设计的更好。

本书基于linux编写的。
平台和版本
平台和版本

第一部分 实施和开发方法
第一章 代码风格

选择适合你的代码风格

代码格式化和布局

包括行的长度,使用空白,使用SQL是最基本的技能。

缩进

本书使用缩进来表示代码块,但不能夸大其重要性。虽然php中不强制缩进,但是缩进是一个有用的工具。

考虑下面的代码
if($month  == 'september' || $month  == 'april' || $month  == 'june' || $month  ==
'november') { return 30;
}
else if($month == 'february') {
if((($year % 4 == 0) && !($year % 100)) || ($year % 400 == 0)) {
return 29;
}
else {
return 28;
}
}
else {
return 31;
}

和下面的代码比较,除了缩进都是相同的。

if($month  == 'september' ||
$month  == 'april'     ||
$month  == 'june'      ||
$month  == 'november') {
return 30;
}
else if($month == 'february') {
if((($year % 4 == 0) && ($year % 100)) || ($year % 400 == 0)) {
return 29;
}
else {
return 28;
}
}
else {
return 31;
}

后一段代码比前一段在逻辑上更好分辨。

当你使用tab代码缩进,你需要做出一致性选择使用硬或软tab,硬是常规选项,而软实际上是由一定量的空格表示,使用软的好处是他们总是相同,我比较喜欢软。当你使用硬,在多个开发人员使用不同的编辑器会造出不一致。

选择tab的宽度,四个空格的标签产生可读的代码。

行长

前面的第一段代码太长,这样不便于跟踪和调试,应该把长行分为多行,例如:

if($month  == 'september' || $month  == 'april' ||
$month  == 'june' || $month  == 'november') {
return 30;
}

可以缩进对齐条件

if($month  == 'september' ||
$month  == 'april' ||
$month  == 'june' ||
$month  == 'november')
{
return 30;
}

这个方法同样适合于函数的参数

mail("postmaster@example.foo",
     "My Subject",
     $message_body,
     "From: George Schlossnagle <george@omniti.com>\r\n");

一般,我会80个字符就要换行,因为这是一个标准unix终端窗口的宽度。

使用空白

$lt = localtime();
$name = $_GET['name'];
$email = $_GET['email'];
$month = $lt['tm_mon'] + 1;
$year = $lt['tm_year'] + 1900;
$day = $lt['tm_day'];
$address = $_GET['address'];

通过空白进行逻辑分组

$name    = $_GET['name'];
$email   = $_GET['email'];
$address = $_GET['address'];
$lt    = localtime();
$day   = $lt['tm_day'];
$month = $lt['tm_mon'] + 1;
$year  = $lt['tm_year'] + 1900;

SQL指引

$query = "SELECT FirstName, LastName FROM employees, departments WHERE
employees.dept_id = department.dept_id AND department.Name = 'Engineering'";

上面的sql组织的不好,可以从以下方面修改:

关键字大写;关键字换行;使用表的别名保持代码整洁

$query = "SELECT firstname,
lastname
FROM employees e,
departments d
WHERE e.dept_id = d.dept_id
AND d.name = 'Engineering'";

控制流结构

两种方式:条件和循环

控制结构使用大括号

php采用c语言风格,单行php条件语句不用使用大括号,例如下面的代码是正确的:

if(isset($name))
print "Hello $name";

但是,这样会引起混乱,应该总是使用大括号

if(isset($name)) {
print "Hello $name";
}
else {
print "Hello Stranger";
}

始终使用大括号

条件语句中三种使用括号的风格

BSD风格我比较喜欢

if ($condition)
{
// statement
}

GNU风格

if ($condition)
{
// statement
}

K&R 风格

if ($condition) {
// statement
}

for和foreach和while
如果for或者foreach循环可以做的事情不应该使用while循环

function is_prime($number)
{
if(($number % 2) != 0) {
return true;
}
$i = 0;
while($i < $number) {
// A cheap check to see if $i is even
if( ($i & 1) == 0 ) {
continue;
}
if ( ($number % $i ) == 0) {
return false;
}
$i++;
}
return true;
}

不小心会增加无限循环,使用for更加自然

function is_prime($number)
{
if(($number % 2) != 0) {
return true;
}
for($i=3; $i < $number; $i++) {
// A cheap check to see if $i is even
if( ($i & 1) == 0 ) {
continue;
}
if ( ($number % $i ) == 0) {
return false;
}
}
return true;
}

对数组迭代的时候foreach比for更好

$array = (3, 5, 10, 11, 99, 173);
foreach($array as $number) {
if(is_prime($number)) {
print "$number is prime.\n";
}
}

这样比使用for更快,因为避免计数器的使用。

使用break和continue控制循环

不需要循环的时候使用break跳出循环

$has_ended = 0;
while(($line =  fgets($fp)) !== false) {
if($has_ended) {
}
else {
if(strcmp($line, '_END_') == 0) {
$has_ended = 1;
}
if(strncmp($line, '//', 2) == 0) {
}
else {
// parse statement
}
}
}

这个例子比前面的更短,而且避免了深层次的嵌套

while(($line =  fgets($fp)) !== false) {
if(strcmp($line, '_END_') == 0) {
break;
}
if(strncmp($line, '//', 2) == 0) {
continue;
}
// parse statement
}

避免很深层的循环

常见的错误是在一个浅循环中使用深层嵌套

$fp = fopen("file", "r");
if ($fp) {
$line = fgets($fp);
if($line !== false) {
// process $line
}  else {
die("Error: File is empty);
}
else {  die("Error: Couldn't open file");
}

消除不必要的嵌套

$fp = fopen("file", "r");
if (!$fp) {
die("Couldn't open file");
}
$line = fgets($fp);
if($line === false) {
die("Error: Couldn't open file");
}
// process $line

命名符号

function test($baz)
{
for($foo = 0; $foo < $baz; $foo++) {
$bar[$foo] = "test_$foo";
}
return $bar;
}

下面的代码使用更有意义的变量名和函数名

function create_test_array($size)
{
for($i = 0; $i < $size; $i++) {
$retval[$i] = "test_$i";
}
return $retval;
}

三类命名规则:

全局变量要使用在全局范围

长时间存在的变量可存在于任何范围但要包含重要信息或大块代码的引用

临时变量用于小部分代码保持临时信息

常量和真正的全局变量

全局变量和常量要使用大写字母,便于辨识。

$CACHE_PATH = '/var/cache/';
...
function list_cache()
{
global $CACHE_PATH;
$dir = opendir($CACHE_PATH);
while(($file = readdir($dir)) !== false && is_file($file)) {
$retval[] = $file;
}
closedir($dir);
return $retval;
}

错误使用全局变量的原因:

它们可以在任何地方被改变不好定位;

污染了全局命名空间,例如使用一个全局变量命名为计数器$counter同时你还有另一个计数器也是$counter,随着代码的增长这种冲突越来越不可避免;

解决方案是使用一个“访问器”函数。

global $database_handle;
global $server;
global $user;
global $password;
$database_handle = mysql_pconnect($server, $user, $password);

可以使用如下的类:

class Mysql_Test {
public $database_handle;
private $server = 'localhost';
private $user = 'test';
private $password = 'test';
public function __construct()
{
$this->database_handle =
mysql_pconnect($this->server, $this->user, $this->password);
}
}

第二章中将探索更有效的方式处理这个例子,当我们处理单例模式和封装类时。

有时候,你需要访问一个特定的变量,像这样:

$US_STATES = array('Alabama', ... , 'Wyoming');

这个例子中类做了太多的事情,如果你想在这里避免全局变量,你可以使用一个访问函数全局数组使用一个静态变量。

function us_states()
{
static $us_states = array('Alabama', ... , 'Wyoming');
return $us_states;
}

长时间存在的变量
应该有简洁描述性的名称,长时间存在的变量不一定是全局的,甚至在主题范围内。

下面例子中变量名帮助理解代码的意思。

function clean_cache($expiration_time)
{
$cachefiles = list_cache();
foreach($cachefiles as $cachefile) {
if(filemtime($CACHE_PATH."/".$cachefile) > time() + $expiration_time) {
unlink($CACHE_PATH."/".$cachefile);
}
}
}

临时变量

临时变量的名称要简明扼要。由于临时变量通常只存在于一个小的代码块,所以他们并不需要有说明性名称。 特别是用于循环的数值变量应该始终被命名为J,K,L,M,和n
等。

比较这个例子

$number_of_parent_indices = count($parent);
for($parent_index=0; $parent_index <$number_of_parent_indices; $parent_index++) {
$number_of_child_indices = count($parent[$parent_index]);
for($child_index = 0; $child_index < $number_of_child_indices; $child_index++) {
my_function($parent[$parent_index][$child_index]);
}
}

例如

$pcount = count($parent);
for($i = 0; $i < $pcount; $i++) {
$ccount = count($parent[$i]);
for($j = 0; $j < $ccount; $j++) {
my_function($parent[$i][$j]);
}
}

这样会更妙

foreach($parent as $child) {
foreach($child as $element) {
my_function($element);
}
}

 多词名称

$numElements = count($elements);

$num_elements = count($elements);

推荐第二种命名方法,原因是:

情况发生变化,你为了保持一致性不得不$CACHEDIR和$PROFANITYMACROSET

数据库不区分大小写;

非英语本土人士会在字典中更好的查到。

函数名

函数名和正常的变量名类似的处理方式,全部小写,多字要用下划线分割,推荐K&R风格:

function print_hello($name)
{
print "Hello $name";
}

foo() 和bar() 反映不出你的代码更多的信息,让你的代码看起来很不专业。

类名

参考官方的Java风格指南,类名应遵循以下规则:

一个类的名字第一个字母是大写;
下划线应该用来模拟嵌套的命名空间;

多字的类名应连接在一起,每个单词的首字母应大写。

class XML_RSS {}
class Text_PrettyPrinter {}

方法名

Java风格的串连字多字的方法名称是第一个字母后的单词第一个字母大写

class XML_RSS
{
function startHandler() {}
}

命名一致性

类似目的的变量保持类似的名称

$num_elements = count($elements);
...
$objects_cnt = count($objects);
推荐下面的风格
$max_elements;
$min_elements;
$sum_elements;
$prev_item;
$curr_item;
$next_item;
匹配变量名和架构名
与数据库中的记录相关联的变量名称应该始终有相匹配的名字。
$query = "SELECT firstname, lastname, employee_id
FROM employees";
$results = mysql_query($query);
while(list($firstname, $lastname, $employee_id) = mysql_fetch_row($results)) {
// ...
}
下面的代码容易混淆
$first_query = "SELECT a,b
FROM subscriptions
WHERE subscription_id = $subscription_id";
$results = mysql_query($first_query);
list($a, $b) = mysql_fetch_row($results);
// perform necessary logic
$new_a = $b;
$new_b = $a;
$second_query = "UPDATE subscriptions
SET a = '$new_a',
B = '$new_b'
WHERE subscription_id = $subscription_id";
Mysql_query($second_query);

开发人员为了保持列名和变量名在update中一致性

$first_query = "SELECT a,b
FROM subscriptions
WHERE subscription_id = $subscription_id";
$results = mysql_query($first_query);
list($b, $a) = mysql_fetch_row($results);
// perform necessary logic
$second_query = "UPDATE subscriptions
SET a = '$a',
B = '$b'
WHERE subscription_id = $subscription_id";
mysql_query($second_query);

这一代码会完全混乱不堪。

避免代码混乱

一致的代码风格让代码看一起是清晰的

避免短的开放的标签

php允许段标签

<?
print "Hello $username";
?>
但是不应该使用!

因为无法打印正常的XML内联文件

<?xml version="1.0" ?>

应该使用长标签

<?php
print "Hello $username";
? >

《Advanced PHP Programming》读书笔记相关推荐

  1. 读书笔记 | 墨菲定律

    1. 有些事,你现在不做,永远也不会去做. 2. 能轻易实现的梦想都不叫梦想. 3.所有的事都会比你预计的时间长.(做事要有耐心,要经得起前期的枯燥.) 4. 当我们的才华还撑不起梦想时,更要耐下心来 ...

  2. 读书笔记 | 墨菲定律(一)

    1. 有些事,你现在不做,永远也不会去做. 2. 能轻易实现的梦想都不叫梦想. 3.所有的事都会比你预计的时间长.(做事要有耐心,要经得起前期的枯燥.) 4. 当我们的才华还撑不起梦想时,更要耐下心来 ...

  3. 洛克菲勒的38封信pdf下载_《洛克菲勒写给孩子的38封信》读书笔记

    <洛克菲勒写给孩子的38封信>读书笔记 洛克菲勒写给孩子的38封信 第1封信:起点不决定终点 人人生而平等,但这种平等是权利与法律意义上的平等,与经济和文化优势无关 第2封信:运气靠策划 ...

  4. 股神大家了解多少?深度剖析股神巴菲特

    股神巴菲特是金融界里的传奇,大家是否都对股神巴菲特感兴趣呢?大家对股神了解多少?小编最近在QR社区发现了<阿尔法狗与巴菲特>,里面记载了许多股神巴菲特的人生经历,今天小编简单说一说关于股神 ...

  5. 2014巴菲特股东大会及巴菲特创业分享

     沃伦·巴菲特,这位传奇人物.在美国,巴菲特被称为"先知".在中国,他更多的被喻为"股神",巴菲特在11岁时第一次购买股票以来,白手起家缔造了一个千亿规模的 ...

  6. 《成为沃伦·巴菲特》笔记与感想

    本文首发于微信公众帐号: 一界码农(The_hard_the_luckier) 无需授权即可转载: 甚至无需保留以上版权声明-- 沃伦·巴菲特传记的纪录片 http://www.bilibili.co ...

  7. 读书笔记002:托尼.巴赞之快速阅读

    读书笔记002:托尼.巴赞之快速阅读 托尼.巴赞是放射性思维与思维导图的提倡者.读完他的<快速阅读>之后,我们就可以可以快速提高阅读速度,保持并改善理解嗯嗯管理,通过增进了解眼睛和大脑功能 ...

  8. 读书笔记001:托尼.巴赞之开动大脑

    读书笔记001:托尼.巴赞之开动大脑 托尼.巴赞是放射性思维与思维导图的提倡者.读完他的<开动大脑>之后,我们就可以对我们的大脑有更多的了解:大脑可以进行比我们预期多得多的工作:我们可以最 ...

  9. 读书笔记003:托尼.巴赞之思维导图

    读书笔记003:托尼.巴赞之思维导图 托尼.巴赞的<思维导图>一书,详细的介绍了思维发展的新概念--放射性思维:如何利用思维导图实施你的放射性思维,实现你的创造性思维,从而给出一种深刻的智 ...

  10. 产品读书《滚雪球:巴菲特和他的财富人生》

    作者简介 艾丽斯.施罗德,曾经担任世界知名投行摩根士丹利的董事总经理,因为撰写研究报告与巴菲特相识.业务上的往来使得施罗德有更多的机会与巴菲特亲密接触,她不仅是巴菲特别的忘年交,她也是第一个向巴菲特建 ...

最新文章

  1. 新疆电信IBSS系统集中联机热备份--案例
  2. jna 不是有效的 win32 应用程序_教你打开程序提示不是有效的win32程序怎么办
  3. 函数中数据存储的问题
  4. win10 git bash 闪退
  5. php ajax 更改状态,phpajax实现无刷新获取天气状态_PHP教程
  6. g++: command not found的解决
  7. obj.href 与 obj.getAttribute(href)的区别
  8. 将python算法转为scala_将Python转换为scalaasp
  9. 读书笔记——思维导图带你看《哲学起步》
  10. python的常量_python常量 (最全常量解析)
  11. 思维导图软件哪个好?不要错过这份思维导图软件合集
  12. excel打印时显示服务器脱机怎么办,excle正在访问打印机!连接局域网打印机在excel中预览,excel自动就关闭是怎么回事...
  13. 2011当选的院士工作职务之一
  14. 国际标准战争的技术真相
  15. 谈谈对java线程的理解(五)--------ReentrantLock之阻塞队列
  16. 被社会毒打的20年毕业的后端
  17. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccc
  18. Leetcode_动态规划、迭代
  19. matlab论文致谢,大学毕业论文致谢信3篇
  20. Ubuntu系统迁移至固态硬盘(生产环境勿用)

热门文章

  1. 深度优先搜索_0基础学算法 搜索篇第一讲 深度优先搜索
  2. 对象特性-----拷贝构造函数的调用
  3. 布袋除尘器过滤风速多少_塑烧板除尘器过滤风速选多少
  4. html缩进两个空格,HTML缩进标准,制表符还是两个空格?
  5. mysql zerofill 性能_比较详细的MySQL字段类型说明
  6. visual studio2010-2015编译部署caffe
  7. 基于pytorch的模型压缩和模型剪枝Model Prune示例
  8. ttc转换ttf字体在线_R 语言画图中英文字体解决方案
  9. python输入多个数字后续操作_有效地确定后续数字范围中的数字是否在有序列表中. (在Python中)...
  10. 实时的激光雷达点云压缩