
《PHP 7开发宝典(第4版)》详细介绍了如何通过添加反馈表单、创建私人区域让授权用户上传自动调整大小的图像,或者将所有内容存储到数据库中,从而使网站更具动态性。作者David Powers更新了他的权威书籍,介绍了新发布的PHP 7,以及这个版本所带来的新技术和变化。新的特性包括太空船运算符、空合并运算符、生成器、在list()函数中使用数组便捷语法、数组解引用,以及使用splat运算符进行数组解包。
PHP和MySQL数据库是创建动态网站更受欢迎的组合。它们是免费的且易于使用,并且许多网络托管公司都提供标准的安装包。本书还涵盖了MariaDB。MariaDB是MySQL的无缝替代品,已经被许多Web服务器所采用。
《PHP 7开发宝典(第4版)》通过一系列实例向你提供了真正有价值的技术方案,并可以直接融入你的网站,优化性能和增加功能,如文件上传、电子邮件反馈表单、图片库和内容管理系统等。创建每个解决方案时,不仅实现了特定功能,还提供了界面设计。
《PHP 7开发宝典(第4版)》不仅提供一系列现成的脚本,而且每个PHP解决方案都建立在以前的基础之上,快速而轻松地教给你PHP和数据库设计的基础知识。学完本书,你将有信心开始编写自己的脚本;如果你不愿意从头开始编写,也可以修改本书提供的代码以满足自己的需求。从本书一开始,作者就向你展示了如何通过采用安全编码实践来轻松地保护网站。
主要内容
● 设计与构建基于PHP的动态网站和应用程序
● 通过可以重用的实际示例开始学习
● 掌握PHP 7的新特性,包括处理数组的新方法
● 使用最新的PHP 7技术、创新和更佳实践
前 言
PHP并不难,但也不像速溶蛋糕那样:只需加水搅拌即可。每个网站都是不同的,因此不可能抓取一个脚本,粘贴到一个网页上,然后就期望它能正常工作。笔者的目标是帮助对编程知之甚少或一无所知的网页设计师获得深入研究代码并根据自己的需求调整代码的信心。
你不需要任何PHP或其他编程语言的经验就可以使用《PHP+7开发宝典(第4版)》;但编程技术确实在快速发展。在前几章之后,你将开始使用相对高级的语言特性。别为理解这些语言特性花费太多时间,把它们视为一个挑战。《PHP+7开发宝典(第4版)》被称为PHP解决方案,其目的是为实际问题提供解决方案,而不是提供一系列毫无价值的练习。
你如何使用《PHP 7开发宝典(第4版)》将取决于你的经验水平。如果你对PHP和编程还不熟悉,请从头开始,并逐步阅读《PHP+7开发宝典(第4版)》。《PHP+7开发宝典(第4版)》按照一个逻辑顺序进行组织,每一章都建立在前面章节的知识和技能的基础上。在描述代码时,笔者试图用简单的语言解释它的功能。笔者避免使用行话,但使用了一些技术术语(每个新术语在第一次出现时都会进行简要描述)。如果你对PHP有更多的经验,可以直接跳转到感兴趣的领域。虽然在没有笔者的解释的情况下你也能理解代码的意义,但笔者希望呈现自己在使用PHP解决问题时理清思路的过程。
细小而重大的变化
这个版本的标题有一点细微的差别。我们在标题里面特意指明是PHP 7。以前的版本简单地称为PHP解决方案;但是《PHP+7开发宝典(第4版)》的编辑和笔者决定明确地表明,这个版本只关注PHP 7,这是目前唯一受支持的PHP版本。除了大大提高了速度之外,PHP 7的一大优点是,它几乎完全向后兼容PHP 5;换句话说,实际上所有在PHP 5上运行的代码都可以无缝地切换到PHP 7的环境中。然而,反过来却不行。《PHP+7开发宝典(第4版)》使用了许多PHP 7的新特性。因此,如果尝试在仍然运行PHP 5的旧服务器上运行PHP 7解决方案中的代码,你很快就会遇到问题。
由于托管公司通常升级他们提供的PHP版本的速度很慢,因此《PHP+7开发宝典(第4版)》的前几个版本为较旧版本的PHP提供了解决方法。这一次,《PHP+7开发宝典(第4版)》没有这样做。对一些读者来说,这意味着在本地测试环境中完美工作的代码在上传到远程服务器上后可能会崩溃。截至2019年中期,每3台运行PHP的Web服务器中就有两台以上仍在使用PHP 5,尽管所有对PHP 5的官方支持都已在2018年12月结束。甚至连PHP 7(7.0)的原始版本都不再受支持。《PHP+7开发宝典(第4版)》中的代码是在PHP 7.3上开发的,尽管在第10章中有一个小的例外(《PHP+7开发宝典(第4版)》提供了解决方法),所有代码都将在PHP 7.2或更高版本上运行。
PHP不像你开了多年的旧车,只要给它足够的爱和油,就不需要更换。PHP不断更新,不仅要添加新功能,还要修复bug和安全问题。即使你对新特性不感兴趣,也应该对安全修复感兴趣。互联网可能是一个疯狂的地方,许多讨厌的角色试图在网站上找到可利用的漏洞。《PHP+7开发宝典(第4版)》包含了很多关于安全性的建议,但是它不能保护你免受PHP核心中发现的安全问题的影响。确保你的远程服务器保持最新状态是将风险降至最低所需的保障。因为PHP是免费的(尽管托管公司对他们的服务收费),所以不会额外增加费用。
这个版本的其他新特点
这个版本仍然沿用以前版本的结构,继续使用相同的Japan Journey网站案例作为主线,因此乍一看,似乎没有什么变化。不过,每一页都做了修订,目的是使描述更清楚。更重要的是,对代码进行了广泛的审查和更新。第9章和第10章中的Upload和ThumbnailUpload类已经被彻底重写,使它们更简单、更健壮。关于使用数组有一个全新的章节;关于编写PHP脚本的章节被分成两部分。第3章现在是对新用户的PHP快速介绍,而第4章则是对初学者和更有经验的读者的PHP快速参考。第4章已经扩展了内容以介绍PHP 7中的新特性。
有关使用MySQL或MariaDB数据库的章节已经过修订,以使代码更加安全。《PHP+7开发宝典(第4版)》还添加了一个PHP解决方案,特别说明了使用超级全局变量$_SERVER['PHP_SELF']可能出现的问题,并提供了一个健壮的解决方案。
使用示例文件
可扫描封底二维码获取《PHP+7开发宝典(第4版)》示例文件。
设置一个PHP开发环境,如第2章所述。解压缩文件并将phpsols-4e文件夹及其所有内容复制到Web服务器的文档根目录中。每章的代码都位于以该章的编号命名的文件夹(如ch01、ch02等)中。按照每个PHP解决方案中的说明进行操作,并将相关文件复制到网站根目录或指定的工作文件夹中。
如果在一章中对一个页面进行多次修改,《PHP+7开发宝典(第4版)》会对文件的不同版本进行编号,比如index_01.php、index_02.php等。复制带有数字的文件时,请从文件名
中删除下画线和数字,这样index_01.php就变成了index.php。如果你使用的程序在将文件从一个文件夹移动到另一个文件夹时提示你更新链接,请不要更新它们。文件中的链接设计用于在目标文件夹中获取正确的图像和样式表。《PHP+7开发宝典(第4版)》已经这样做了,因此你可以使用文件比较工具检查你的文件与笔者的文件。
如果你没有文件比较工具,笔者强烈建议你安装一个。当你试图找出你的版本和笔者的版本之间的差异时,这将节省大量时间。在几十行代码中,很难找到缺少分号或类型错误的变量。Windows用户可从http://WinMerge.org/免费下载WinMerge。笔者使用Beyond Compare(www.scootersoftware.com),它现在提供Windows、macOS和Linux版本。这个工具不是免费的,但功能很强大,而且价格合理。Mac上的BBEdit包含一个文件比较工具。如果你愿意在Mac上使用终端程序,那么默认情况下会安装diff实用程序。
目 录
第1章 PHP介绍和PHP使用对象 1
1.1 PHP的演进 2
1.2 使用PHP实现页面动态效果 2
1.3 学习和使用PHP的难易程度 4
1.3.1 复制和粘贴本书的PHP代码 5
1.3.2 PHP的安全性 5
1.4 编写PHP代码需要使用的软件 5
1.5 本章小结 7
第2章 准备使用PHP 9
2.1 检测网站是否支持PHP 9
2.2 安装本地测试环境 11
2.3 在Windows上设置PHP开发测试环境 11
2.3.1 设置Windows以显示文件扩展名 12
2.3.2 选择Web服务器 12
2.3.3 在Windows上安装一体化软件安装包 12
2.4 在macOS上设置PHP开发测试环境 12
2.4.1 安装MAMP 13
2.4.2 测试和配置MAMP 13
2.5 PHP文件在Windows和Mac上的存放位置 15
2.6 查看PHP设置 16
2.6.1 使用phpinfo()命令显示服务器配置 16
2.6.2 编辑php.ini文件 18
2.7 后续学习内容 20
第3章 编写PHP脚本 21
3.1 PHP概况 21
3.1.1 告诉服务器处理PHP页面 22
3.1.2 将PHP代码嵌入网页 22
3.1.3 将PHP代码保存在外部文件中 23
3.1.4 使用变量表示变化的值 23
3.1.5 用分号结束语句 26
3.1.6 注释脚本 26
3.1.7 使用数组存储多个变量 27
3.1.8 PHP内置的超级全局数组 29
3.1.9 理解引号的使用 29
3.1.10 根据条件语句做出决策 32
3.1.11 比较运算符 33
3.1.12 使用缩进和空格提高代码可读性 34
3.1.13 对重复性任务使用循环 35
3.1.14 使用函数执行预设的任务 35
3.1.15 显示PHP输出 36
3.1.16 理解PHP错误消息 38
3.2 本章小结 39
第4章 PHP:快速参考 41
4.1 在已有的网站中使用PHP 41
4.2 PHP中的数据类型 41
4.2.1 检查变量的数据类型 43
4.2.2 显式更改变量的数据类型 43
4.2.3 检查变量是否已定义 44
4.3 使用PHP进行计算 44
4.3.1 算术运算符 44
4.3.2 使用递增和递减运算符 45
4.3.3 运算符的优先级 46
4.3.4 组合计算和赋值运算符 46
4.4 字符串连接 46
4.5 你想知道的关于引号的一切 47
4.5.1 PHP处理字符串中的变量的方式 47
4.5.2 在双引号内使用转义序列 48
4.5.3 在字符串中嵌入关联数组元素 48
4.5.4 使用heredoc语法避免转义引号 49
4.6 创建数组 50
4.6.1 创建索引数组 51
4.6.2 创建关联数组 51
4.6.3 创建空数组 52
4.6.4 多维数组 52
4.6.5 使用print_r()函数检查数组 53
4.7 PHP中的逻辑运算 54
4.7.1 显式布尔值 54
4.7.2 隐式布尔值 54
4.7.3 根据两个值的比较结果做决策 55
4.7.4 复合条件 56
4.7.5 对决策链使用switch语句 56
4.7.6 使用三元运算符 58
4.7.7 使用空合并运算符设置默认值 59
4.8 使用循环重复执行代码 59
4.8.1 while循环和do…while循环 59
4.8.2 用途多样的for循环 60
4.8.3 使用foreach循环遍历数组和对象 61
4.8.4 中断循环 62
4.9 使用函数模块化代码 63
4.9.1 向函数传递值 63
4.9.2 为参数设置默认值 64
4.9.3 变量的作用域 65
4.9.4 从函数返回值 66
4.9.5 生成器—— 一种不断产生输出的特殊类型的函数 66
4.9.6 通过引用传递参数 67
4.9.7 接收可变数量参数的函数 68
4.9.8 自定义函数的位置 69
4.10 理解PHP类和对象 69
4.11 为类和函数指定数据类型(可选) 70
4.12 处理错误和异常 72
4.13 动态创建新变量 73
4.14 后续内容 74
第5章 使用包含文件 75
5.1 包含来自外部文件的代码 75
5.1.1 PHP包含命令 75
5.1.2 PHP查找包含文件的位置 76
5.1.3 为包含文件选择正确的文件扩展名 81
5.1.4 创建内容会发生变化的页面 91
5.1.5 防止包含文件出错 100
5.1.6 抑制已部署网站的错误消息 101
5.1.7 不能在PHP包含文件中使用网站根相对链接 106
5.1.8 选择获取包含文件的位置 107
5.1.9 包含文件的安全注意事项 108
5.1.10 修改include_path指令 108
5.2 本章回顾 111
第6章 在线表单 113
6.1 PHP从表单收集信息的方式 113
6.1.1 理解post和get的区别 115
6.1.2 使用PHP超级全局数组获取表单数据 118
6.2 处理和验证用户输入 118
6.2.1 创建可重用的脚本 119
6.2.2 在表单不完整时保留用户输入 127
6.2.3 过滤潜在攻击 129
6.3 发送电子邮件 131
6.4 处理多项选择表单元素 141
6.5 本章回顾 150
第7章 使用PHP管理文件 151
7.1 检查PHP是否能打开文件 151
7.1.1 在Windows服务器根外创建文件夹以便进行本地测试 152
7.1.2 影响文件访问的配置设置 153
7.2 读写文件 153
7.2.1 在单个操作中读取文件 154
7.2.2 打开和关闭用于读/写操作的文件 158
7.3 探索文件系统 167
7.3.1 使用scandir()函数检查文件夹 167
7.3.2 使用FilesystemIterator类检查文件夹的内容 168
7.3.3 使用RegexIterator限制文件类型 171
7.4 访问远程文件 175
7.4.1 使用新闻源和其他RSS源 176
7.4.2 使用SimpleXML 177
7.5 创建下载链接 181
7.6 本章回顾 183
第8章 使用数组 185
8.1 修改数组元素 185
8.1.1 PHP解决方案8-1:使用循环修改数组元素 186
8.1.2 PHP解决方案8-2:使用array_walk()函数修改数组元素 188
8.1.3 PHP解决方案8-3:使用array_map()函数修改数组元素 190
8.2 合并数组 193
8.2.1 使用数组并集操作符 193
8.2.2 使用array_merge()和array_merge_recursive()函数 195
8.2.3 将两个索引数组合并为关联数组 197
8.2.4 比较数组 197
8.2.5 PHP解决方案8-4:用逗号连接数组 198
8.3 数组排序 201
8.3.1 PHP解决方案8-5:使用宇宙飞船操作符进行自定义排序 203
8.3.2 使用array_multisort()函数进行复杂排序 205
8.3.3 PHP解决方案8-6:使用array_multisort()函数对多维数组排序 206
8.3.4 PHP解决方案8-7:查找数组的所有排列 208
8.4 处理数组数据 210
8.4.1 PHP解决方案8-8:自动构建嵌套列表 210
8.4.2 PHP解决方案8-9:从JSON中提取数据 214
8.5 自动将数组元素分配给变量 217
8.5.1 使用extract()函数 218
8.5.2 使用list() 218
8.5.3 使用list()的数组快捷语法 219
8.5.4 PHP解决方案8-10:使用生成器处理CSV文件 219
8.6 使用扩张操作符从数组中解包参数 222
8.7 本章回顾 224
第9章 上传文件 225
9.1 PHP处理文件上传的方式 225
9.1.1 检查服务器是否支持上传 226
9.1.2 向表单添加文件上传字段 227
9.1.3 理解$_FILES数组 228
9.1.4 建立上传 230
9.2 上传文件 230
9.2.1 将临时文件转移到上传文件夹 231
9.2.2 PHP解决方案9-1:创建基本的文件上传脚本 231
9.3 创建PHP文件上传类 234
9.3.1 定义PHP类 235
9.3.2 检查上传文件的错误 242
9.3.3 修改受保护的属性 245
9.4 一次上传多个文件 252
9.5 使用Upload类 258
9.6 上传文件时需要注意的检查点 258
9.7 本章回顾 259
第10章 生成缩略图 261
10.1 检查服务器的能力 261
10.2 动态处理图像 262
10.3 上传时自动调整图像大小 281
10.3.1 扩展类 281
10.3.2 使用Thumbnail-Upload类 287
10.4 本章回顾 288
第11章 记住用户的输入:简单登录表单和多页表单 289
11.1 会话的定义和工作原理 289
11.1.1 创建PHP会话 292
11.1.2 创建和销毁会话变量 292
11.1.3 销毁会话 292
11.1.4 重新生成会话ID 293
11.1.5 Headers already sent错误 293
11.2 使用会话限制访问 294
11.2.1 PHP解决方案11-1:一个简单的会话示例 294
11.2.2 使用基于文件的身份验证 299
11.2.3 保护密码的安全 299
11.3 设置会话的时间限制 321
11.4 在多页表单之间传递信息 324
11.5 本章回顾 331
第12章 数据库入门 333
12.1 选择数据库:MySQL或MariaDB 333
12.2 数据库存储数据的原理 334
12.2.1 主键的工作原理 335
12.2.2 用主键和外键链接多个数据表 336
12.2.3 把信息分成小块 337
12.2.4 设计良好数据库的标准 337
12.3 使用图形界面管理MySQL 337
12.4 创建名为phpsols的数据库 339
12.4.1 MySQL的命名规则 339
12.4.2 使用phpMyAdmin创建新数据库 340
12.4.3 创建特定于数据库的用户账户 341
12.4.4 创建数据库表 344
12.4.5 在表中插入记录 346
12.4.6 创建用于备份和数据迁移的SQL文件 350
12.5 在MySQL中选择正确的数据类型 354
12.5.1 存储文本 354
12.5.2 存储数字 355
12.5.3 存储日期和时间 355
12.5.4 存储预定义列表 356
12.5.5 存储二进制数据 356
12.6 本章回顾 356
第13章 使用PHP和SQL连接数据库 357
13.1 检查远程服务器设置 357
13.2 PHP与数据库通信的过程 358
13.2.1 使用MySQLi进行连接 359
13.2.2 使用PDO进行连接 359
13.2.3 PHP解决方案13-1:创建可重用的数据库连接器 360
13.2.4 清理从数据库获取的文本内容 363
13.2.5 查询数据库并显示结果 364
13.3 使用SQL与数据库交互 371
13.3.1 编写SQL查询 371
13.3.2 优化由SELECT查询检索的数据 373
13.4 了解SQL注入的危险性 376
13.5 使用准备好的语句处理用户输入 381
13.5.1 在MySQLi中将变量嵌入准备好的语句中 382
13.5.2 在PDO中将变量嵌入准备好的语句中 387
13.6 本章回顾 394
第14章 创建动态图片库 397
14.1 不在数据库中存储图像的原因 398
14.2 规划画廊 398
14.3 将图片库静态页面上的元素转换为PHP 400
14.4 构建动态元素 403
14.4.1 通过查询字符串传递信息 403
14.4.2 创建有多列的表 407
14.4.3 分页显示数量较多的记录 409
14.5 本章回顾 416
第15章 数据库内容管理 417
15.1 建立内容管理系统 417
15.1.1 创建blog数据库表 418
15.1.2 创建基本的插入和更新表单 419
15.1.3 插入新记录 421
15.1.4 链接到更新和删除页面 425
15.1.5 更新记录 429
15.1.6 删除记录 439
15.2 4个基本SQL命令的语法 440
15.2.1 SELECT命令 441
15.2.2 INSERT命令 443
15.2.3 UPDATE命令 443
15.2.4 DELETE命令 444
15.3 安全和错误消息 444
15.4 本章回顾 445
第16章 格式化文本和日期 447
16.1 显示文本摘要 447
16.1.1 提取固定数量的字符 447
16.1.2 在一个完整的单词上结束摘录 449
16.1.3 提取第一段文件 450
16.1.4 显示段落 450
16.1.5 提取完整的语句 452
16.2 构建日期 456
16.2.1 MySQL处理日期的方式 456
16.2.2 在MySQL中插入日期 460
16.2.3 在PHP中处理日期 466
16.3 本章回顾 481
第17章 从多个表中抽取数据 483
17.1 理解表的关系 483
17.2 将图片关联到文章 485
17.2.1 改变现有表的结构 485
17.2.2 在表中插入外键 487
17.2.3 从多张表中选择记录 493
17.2.4 查询不包含匹配外键的记录 498
17.2.5 创建智能链接 500
17.3 本章回顾 501
第18章 管理多个数据库表 503
18.1 维护引用完整性 503
18.1.1 支持事务和外键约束 504
18.1.2 将记录插入多个表中 507
18.1.3 创建交叉引用表 508
18.1.4 获取上传图片的文件名 509
18.1.5 修改插入表单以处理多个表 510
18.2 更新和删除多个表中的记录 523
18.2.1 更新交叉引用表中的记录 523
18.2.2 将多个查询视为事务中的一个块 526
18.2.3 在删除记录时保留引用完整性 534
18.2.4 创建具有外键约束的删除脚本 538
18.2.5 创建没有外键约束的删除脚本 539
18.3 本章回顾 540
第19章 使用数据库进行用户身份验证 541
19.1 选择密码存储方法 541
19.2 使用散列密码 542
19.2.1 创建表来存储用户的详细信息 542
19.2.2 在数据库中注册新用户 542
19.3 使用密钥加密 550
19.3.1 创建用于存储用户详细信息的表 550
19.3.2 注册新用户 551
19.3.3 使用双向加密的用户身份验证 553
19.3.4 解密密码 554
19.4 更新用户的详细信息 555
19.5 后续学习 555
PHP 7这个版本仍然沿用以前版本的结构,继续使用相同的Japan Journey 网站案例作为主线,因此乍一看,似乎没有什么变化。不过,每一页都做了修订,目的是使描述更清楚。更重要的是,对代码进行了广泛的审查和更新。第9章和第10章中的 Upload 和ThumbnailUpload类已经被彻底重写,使它们更简单、更健壮。关于使用数组有一个全新的章节;关于编写PHP脚本的章节被分成两部分。第3章现在是对新用户的PHP快速介绍,而第4章则是对初学者和更有经验的读者的PHP快速参考。第4章已经扩展了内容以介绍 PHP7中的新特性。
有关使用MySQL或MariaDB数据库的章节已经过修订,以使代码更加安全。本书还添加了一个PHP解决方案,特别说明了使用超级全局变量S_SERVER['PHP_SELF]可能出现的问题,并提供了一个健壮的解决方案。
David Powers已经累计发布了三十多个关于PHP的视频培训课程和书籍。这些课程和书籍都非常成功。他以前是BBC电台和电视台的记者,在任职记者期间,花费了很大一部分时间在日本报道泡沫经济的兴衰。他擅长用简单且通俗易懂的语言分析复杂的问题。这种能力也体现在他的关于PHP和Web开发的文章中。
David最初是在20世纪90年代初作为BBC日本电视台的编辑参与网络开发。由于没有营销预算,他开发了一个双语网站来推广这个渠道。离开BBC以后,他继续为一家国际咨询公司开发双语在线数据库,并在英国两所大学讲授网络开发课程。除了写作和制作视频培训课程外,他还是北伦敦一家慈善机构的受托人。该慈善机构为退休人员和不再全职工作的人员提供教育设施。