PHP 01
PHP 01
第1章 PHP入门与环境搭建
PHP概述
- Hypertext Preprocessor
- Web程序开发语言
- 是一种服务器端、跨平台的脚本语言
- 简单、易学
PHP的运行过程
PHP 开发工具其实包括以下四种: - PHP服务器组件。
- PHP IDE(Integrated Development Environment,集成开发环境)。
- MySql管理工具
- 文本编辑器
第2章 PHP基础语法
2.1 PHP基本语法
可嵌入到HTML中
运行在服务器端的脚本语言
语法:
1 |
|
PHP标记符“”和“?>”示例代码:
1 | <!DOCTYPE html> |
注释可以理解为代码的解释说明,一般添加到代码的上方或代码的尾部。示例代码:
1 |
|
由一条或多条PHP语句构成,每条语句都以英文分号“;”结束。示例代码:
1 |
|
2.2 常量
由英文字母、下划线、和数字组成,但数字不能作为首字母出现。 (常量名不需要加 $ 修饰符)。
示例代码:
1 |
|
2.3 变量
用于存储信息的”容器”。变量是指程序运行过程中其值可以变化的量。
示例代码:
1 |
|
PHP中的变量名称遵循以下约定:
在PHP中的变量名是区分大小写的
变量名必须以“$”
开始
变量名开头可以以“_”
开头
变量名开头不能以数字字符开头
变量作用域:
local
global
static
parameter
示例代码:
1 |
|
2.4 数据类型
PHP 支持以下几种数据类型:
String(字符串)
一个字符串是一串字符的序列,就像 “Hello world!”。
用单引号或者双引号括起来。
示例代码:
1 |
|
Integer(整型)
整数是一个没有小数的数字。整数规则如下:
整数必须至少有一个数字 (0-9)
整数不能包含逗号或空格
整数是没有小数点的
整数可以是正数或负数
十进制, 十六进制或八进制。
示例代码:
1 |
|
Float(浮点型)
浮点数是带小数部分的数字,或是指数形式。
示例代码:
1 |
|
Boolean(布尔型)
布尔型可以是 TRUE 或 FALSE。
常用于条件判断
示例代码:
1 | $x=true; |
Array(数组)
Object(对象)
NULL(空值)
Resource(资源类型)
2.5 数据类型的转换
2.6 数据的输出
第3章 运算符和表达式
3.1 算术运算符
常用算术运算符
常见且容易理解的运算符有“+”“-”“*”“/”“%”
,即加减乘除和取余。运算规则和数学中的运算规则一致,先算乘除再算加减,有括号的先算括号内的数。
累加、累减运算符
累加、累减运算符即“++”“--”
,常用在变量的前面或后面,对变量进行加1或减1操作。但用在变量后和用在变量前却有着很大的差别,比如$b=$a++;或$b=$a–;,程序会先把$a的值赋给$b,然后执行++或–操作
3.2 字符串运算符
字符串运算符把两个字符串连接起来,变成一个新的字符串。字符串运算符用“.”表示,如果字符串运算符左右两边任一操作数或两个操作数都不是字符串类型,那么会将操作数先转换成字符串,再执行连接操作;如果变量是整型或浮点型,PHP会自动将它们转换为字符串输出,然后进行连接。
3.3 赋值运算符
赋值运算符的作用是把一定的数据值加载给特定变量,最基本的赋值运算符是“=”,用于对变量赋值,因此左边只能是变量,而不能是表达式。常用的赋值运算符如下表所示。
3.4 比较运算符
一般来说,比较运算符常用在if条件语句中,用来判断程序该跳转到哪个分支。if语句就相当于生活中从一个起点到达一个或多个终点,有很多条路,该走哪一条需要我们选择,需要我们判断。比较运算符的种类很多,如表所示。
3.5 逻辑运算符
逻辑运算符和比较运算符最重要的功能是逻辑判断和运算,在许多PHP应用程序中都起到了重要作用,它们常用在控制结构中。逻辑和、逻辑或、逻辑否都是逻辑运算符,逻辑运算符如表所示
3.6 按位运算符
按位运算符需要把数值转换成二进制数据,用二进制数据进行运算,把各“位”对齐进行按位处理。例如$a=(11&14),需要先把11转换成二进制数(1011)2,把14也转换成二进制数(1110)2,然后进行按位和运算,即对应的二进制都是1,结果为1,最终结果为(1010)2,即十进制的10,按位运算符的含义如表所示。
3.7 错误控制运算符
错误控制运算符用“@”表示。在操作数之前使用,用来屏蔽错误信息的生成。有的时候不能将程序的错误信息全部显示给客户,错误信息里可能包含后台中很多保密的信息。为了将信息屏蔽,可以在容易发生错误的程序代码前加入“@”符号。如下所示:
1 |
|
3.8 三元运算符
三元运算符语法格式为:
表达式?语句1:语句2
如果表达式成立,执行语句1,否则执行语句2
实例代码:
1 |
|
3.9 运算符的优先级和结合规则
运算符的优先级和结合规则其实和正常的数学运算符的结合规则十分相似。
加减乘除的先后顺序同数学运算中的完全一致。
对于括号,先括号内,再括号外。
对于赋值,由右向左运行,即依次从右边向左边的变量进行赋值。
3.10 表达式
PHP主要有5种表达式,即数学表达式(如2+3*4
)、字符串表达式(如”abc”.”de”)、赋值表达式(如$a+=$b)、关系表达式(如$i= =6)和逻辑表达式(如$a||$b&&$c
)。
表达式包含“操作数”和“操作符”。操作数可以是变量,也可以是常量。操作符则体现了要表达的各个行为,如逻辑判断、赋值、运算等。
第4章 流程控制语句
4.1 流程控制概述
流程控制,也叫控制结构,主要是指根据需要让程序转向执行指定的语句。PHP中的控制结构语句分为4类:顺序控制语句、条件控制语句、循环控制语句和跳转控制语句。其中顺序控制语句是从上到下执行的,这种结构没有分支和循环,是PHP程序中最简单的结构。
条件控制语句:if和switch
循环控制语句:while、do-while、for和foreach
跳转控制语句:break、continue和return
4.2 条件控制语句
if语句的语法格式为:
if(expr)
statement;
实例代码:
1 |
|
if…else语句,其语法格式为:
if(expr){
statement 1;
}
else{
statement 2;
}
实例代码:
1 |
|
if…elseif…else语句
考虑到if…else语句只能选择两种结果,要么执行真,要么执行假。当条件表达式有多种取值时,选择结果超两种以上,if…else语句就无法实现该程序。此时可以使用多分支选择语句——if…elseif…else语句,其语法格式为:
1 | if(expr1){ |
switch语句
在程序设计中,所有依据条件做出判定的问题都可以用前面介绍的不同类型的if语句来解决。为了避免if语句冗长,提高程序的可读性,可以使用另外一种选择控制语句——switch分支控制语句。
4.3 循环控制语句
while循环语句的语法格式为:
while(expr)
{
statement;
}
实例代码:
1 |
|
do-while循环语句的语法格式为:
do{
statement;
}
while(expr);
实例代码:
1 |
|
for循环语法格式为:
for(expr1; expr2; expr3)
{
statement;
}
实例代码:
1 |
|
foreach循环语法格式为:
foreach(arry_expression as $value){
statement;
}
或
foreach(arry_expression as $key->value){
statement;
}
实例代码:
1 |
|
4.4 跳转语句
break语句
break语句用于结束当前的循环,包括while循环语句、do-while循环语句、for循环语句、foreach循环语句和switch分支语句的执行。
break语句不仅可以跳出当前循环,还可以指定跳出几重循环,格式如下:
break n;
参数n指定要跳出的循环数量。
continue语句
程序执行break语句后,将跳出循环,并继续执行循环体后续的语句。
实例代码:
1 |
|
exit语句
exit语句的作用是终止整个PHP程序的执行,exit语句后的所有PHP代码都不会执行。格式如下:void exit([string message]);
实例代码:
1 |
|
第5章 数组
5.1 数组概述
数组是一个可以保存很多值的变量。可以把数组看成一个数值列表。数组中的值称为元素。数组中的每个元素都是通过唯一的索引进行引用的。访问一个元素的值——不管是创建、读取、赋值还是删除这个元素,都要用到这个元素的索引。包括PHP在内的许多现代程序设计语言都支持两类数组:
索引数组:这类数组的每个元素都是通过一个数值型索引进行引用的。
关联数组:这类数组的元素是通过哈希函数或映射进行引用的。
5.2 创建数组
新建数组变量的最简单方法是使用PHP内置的array()构造函数。array()构造函数是一个典型的数组函数,用户可以用它创建一个新数组,这个新数组可以是空数组,也可以是在定义时给定数组的元素。比如创建如下:
1 | foods数组: |
5.3 访问数组中的元素
创建了数组之后,如何访问数组中的元素呢?事实上,数组元素的访问方法与字符串中单个字符的访问方法一样:
1 | $foods = array( "饼干", "牛奶", "蛋糕", "牛排" ); |
实例代码:
1 |
|
5.4 用foreach()循环访问数组
正如我们已经看到的,通过将each()函数与while循环相结合,可以逐一访问数组的全部元素。事实上,还有一种更简单的方法来循环访问数组,那就是使用foreach语句。
实例代码:
1 | $authors = array( "张三", "李四", "王五", "赵六" ); |
5.5 多维数组
PHP数组可以存储包括资源、对象在内的任何类型的值,更重要的是,数组还可以包含其他数组。
实例代码:
1 |
|
多维数组的循环访问实例代码:
1 |
|
5.6 数组的操作
数组的排序
在大多数程序设计语言中,都有一个很重要的功能,即可以按顺序对数组的元素进行排序。关于数组的排序,PHP语言提供了不少于12个与数组排序有关的函数。
实例代码:
1 | $authors = array( "张三", "李四", "王五", "赵六" ); |
添加和删除数组元素
我们已经介绍过用方括号方法可以给数组添加元素。例如:
$myArray[] = “new value”;
$myArray[“newKey”] = “new value”;
对于一些简单的情况,这样添加元素是可以的。
实例代码:
1 | $authors = array( "张三", "李四", "王五", "赵六" ); |
数组的合并
假如我们想把多个数组合并成一个大数组,则需要使用array_merge()函数。这个函数需要一个或多个数组作为参数,然后返回合并后的数组,原来的数组不受影响。
实例代码:
1 | $authors = array( "张三", "李四" ); |
数组与字符串之间的转换
PHP提供了几个函数,允许我们把字符串转换成数组,或者把数组转换为字符串。为了把字符串转换为数组,需要使用explode()函数。这个函数需要一个字符串作为参数,它会根据特定的分隔符把字符串分解成多个字符块,然后把分解得到的字符块保存到一个数组中,最后返回这个数组。
实例代码:
1 | $WordString = "A,B,C,D,E"; |
第6章 PHP函数
6.1 创建和使用简单函数
创建用户自定义函数的语法如下:
function function_name()
{
statement(s);
}
实例代码:
1 | function firstname() |
6.2 创建和调用接受参数的函数
编写接受参数的函数的语法如下所示:
function function_name($arg1, $arg2, …){
statement(s);
}
实例代码:
1 | username: <input type="text" name="username" size="20" |
6.3 设置参数默认值
PHP允许函数拥有默认的参数值。要做到这些,只需要在函数定义中为参数赋值即可:
1 | function show_first($first= 'world') { |
6.4 创建和使用带有返回值的函数
函数不仅可以接受参数,还能够返回值,这只需要两个步骤即可。首先,在函数中使用返回语句。其次,在调用函数时以某种方式使用输出。下面是接受两个参数并返回一个值的函数的基本格式:
1 | function show_name($first, $last) { |
6.5 理解变量的作用域
全局声明的语法如下:
function function_name($args) {
global $variable;
statement(s);
}
实例代码:
1 |
|
第7章 面型对象基础知识
7.1 面向对象的基本概念
7.1.1 类
类是属性和方法的集合,是面向对象编程的核心和基础,通过类可以对零散的用于实现某项功能的代码进行有效管理。
例如,创建一个员工类,包括4个属性——姓名、身高、年龄和性别,定义4个方法——上班、工作、下班和开会。
7.1.2 对象
类只是具备某项功能的抽象模型,在实际应用中还需要对类进行实例化,这样就引入了对象的概念。对象是对类进行实例化后的产物,是一个实体。
可以这样理解对象和类的关系:对象实际上就是“有血有肉的、能摸得到且看得见的”一个类。
7.1.3 面向对象编程的三大特点
- 封装性
封装性,也可以称为信息隐藏。就是将一个类的使用和实现分开,只保留有限的接口(方法)与外部联系。 - 继承性
继承性就是派生类(子类)自动继承一个或多个基类(父类)中的属性与方法,并可以重写或添加新的属性或方法。 - 多态性
多态性是指同一个类的不同对象,调用同一个方法可以获得不同的结果。这种技术称为多态性。
7.2 PHP与对象
7.2.1 类的定义
类定义的格式如下:
1 |
|
7.2.2 成员方法
类中的函数被称为成员方法。下面就创建一个员工类,并添加成员方法。
1 |
|
7.2.3 类的实例化
类的成员方法已经添加,接下来就使用成员方法。
首先要对类进行实例化,实例化是通过关键字new来声明一个对象。其次是使用如下格式调用要使用的成员方法:对象名->成员方法
7.2.4 成员变量
类中的变量,也称为成员变量(有时也称属性或字段)。成员变量用来保存数据信息,或通过与成员方法进行交互来实现某项功能。
定义成员变量的格式为:关键字 成员变量名
关键字可以使用public、private、protected、static和final中的任意一个。
访问成员变量和访问成员方法是一样的。只要把成员方法换成成员变量即可,格式为:对象名->成员变量
7.2.5 类常量
既然类中有变量,当然也会有常量。常量就是不会改变的量,是恒值,圆周率是众所周知的一个常量。使用关键字const定义常量,例如:const P=3.1415;
常量和变量的输出是不一样的。常量不需要实例化对象,直接由”类名::常量名”调用即可。常量的输出格式为:类名::常量名
7.2.6 构造方法和析构方法
- 构造方法
构造方法是生成对象时自动执行的成员方法,作用就是初始化对象。构造方法可以没有参数,也可以有多个参数。构造方法的定义格式如下:void __construct([mixed args [.…]])
上述定义中的“__”
是两条下画线。
构造方法是在初始化对象时使用的。如果类中没有构造方法,那么PHP会自动生成一个。自动生成的构造方法没有任何参数,没有任何操作。 - 析构方法
析构方法的作用和构造方法正好相反,在对象被销毁时调用,作用是释放内存。定义析构方法的格式为:void __destruct(void)
PHP使用的是一种“垃圾回收”机制,能自动清除不再使用的对象,释放内存。也就是说,即使不使用unset()函数,析构方法也会自动被调用,这里只是明确一下析构方法在何时被调用。一般情况下是不需要手动创建析构方法的。
7.2.7 继承和多态的实现
- 继承
子类继承父类的所有成员变量和方法,包括构造方法。当子类被实例化时,PHP会先在子类中查找构造方法,如果子类有自己的构造方法,会先调用子类中的构造方法:当子类中没有时,PHP则去调用父类中的构造方法,这就是继承。
继承是通过关键字extends来声明的,格式如下:
1 | class subClass extends superClass{ |
subClass为子类名称,superclass为父类名称。
2. 多态
多态好比有一个成员方法,让人家去游泳,这时有人带游泳圈,有人拿浮板,还有人什么也不带。虽是同一个方法,却产生了不同的形态,这就是多态。
多态存在两种形式:覆盖和重载。
覆盖,就是在子类中重写父类的方法,而在子类的对象中虽然调用的是父类中相同的方法,但返回的结果是不同的。
重载,这是多态的另一种实现。函数的重载是指一个标识符被用作多个函数名,且能够通过函数的参数个数或参数类型将这些同名函数区分开来,以使调用不发生混淆。
7.2.8 “$this->”和“::”的使用
子类不仅可以调用自己的变量和方法,也可以调用父类中的变量和方法,而对于其他不相关的类成员同样可以调用。PHP是通过伪变量“$this->”和作用域操作符“::”来实现这些功能的。
$this
->
调用成员方法就是用对象名加方法名,格式为“对象名->方法名”。但在定义类(如Employee类)时,根本无法得知对象的名称是什么,这时如果想调用类中的方法,就要用伪变量$this->。$this
的意思就是本身,所以$this
->只可以在类的内部使用。- “::”
相比伪变量“$this”只能在类的内部使用,操作符“::”更为强大,它可以在没有声明任何实例的情况下访问类中的成员方法或成员变量。使用操作符“::”的通用格式为关键字::变量名/常用名/方法名
这里的关键字分为以下3种情况:
parent:可以调用父类中的成员变量、成员方法和常量。
self:可以调用当前类中的静态成员和常量。
类名:可以调用该类中的变量、常量和方法。
7.2.9 数据隐藏
- public(公共成员)
顾名思义,就是可以公开的、没有必要隐藏的数据信息。可以在程序中的任何位置(类内、类外)被其他的类和对象调用。子类可以继承和使用父类中所有的公共成员。
在本章的前半部分,所有的变量都被默认声明为public,而所有的方法在默认状态下也是public,所以对变量和方法的使用显得十分混乱。为了解决这个问题,就需要使用第二个关键字private。 - private(私有成员)
被private关键字修饰的变量和方法,只能在所属类的内部被调用和修改,不可以在类外被访问,在子类中也不可以。 - protected(受保护成员和变量)
private关键字可以将数据完全隐藏起来,除在类的内部外,在其他地方都不可以调用,子类也不可以。对于有些变量,希望子类能够调用,但对于另外的类来说,还要做到封装。这时,就可以使用protected关键字。
被protected修饰的类成员,可以在类的内部和子类中被调用,在其他地方都不可以被调用。
7.2.10 静态变量(方法)
不是所有的变量(方法)都要通过创建对象来调用,还可以通过给变量(方法)加上static关键字来直接调用。调用静态成员的格式为:
关键字可以是:关键字:静态成员
self,在类的内部调用静态成员时使用。
静态成员所在类的类名,在类外调用类内部的静态成员时使用。
7.3 PHP对象的高级应用
7.3.1 final关键字
final的中文含义是“最终的”“最后的”。被final修饰过的类和方法就是“最终的版本”。如果有一个类的格式为:
1 | final class class name{ |
就说明该类不可以再被继承,也不能再有子类。
7.3.2 抽象类
抽象类是一种不能被实例化的类,只能作为其他类的父类使用。抽象类使用abstract关键字来声明,格式为:
1 | abstract class AbstractName{ |
抽象类和普通类相似,包含成员变量和成员方法。两者的区别在于:抽象类至少要包含一个抽象方法。抽象方法没有方法体,其功能的实现只能在子类中完成,抽象方法也是使用abstract关键字来修饰的,格式为:abstract function abstractName();
7.3.3 接口的使用
继承特性简化了对象、类的创建,增加了代码的可重用性。但PHP只支持单继承,如果想实现多重继承,就要使用接口。PHP可以实现多个接口。
接口通过interface关键字来声明,并且接口中只能包含未实现的方法和一些成员变量,格式如下:
1 | interface InterfaceName{ |
子类是通过implements关键字来实现接口的,如果要实现多个接口,那么每个接口之间应使用逗号隔开。而且接口中所有未实现的方法都需要在子类中全部实现,否则PHP将会出现错误。格式如下:
1 |
|
7.3.4 克隆对象
- 克隆对象
在PHP中,对象被当作普通的数据类型使用。如果想引用对象,需要使用“&”来声明,否则会按照PHP的默认方式来按值传递对象。 __clone()
方法
有时除单纯地克隆对象外,还需要克隆出来的对象拥有自己的属性和方法。这时就可以使用__clone()
方法来实现。__clone()
方法的作用是:在克隆对象的过程中,调用__clone()
方法,可以使克隆出来的对象保持自己的一些方法及属性。
7.3.5 比较对象
通过克隆对象,知道了表达式$Object2 = $Object1和$Object2 = clone $Object1
所表示的不同含义。
但在实际开发中,还需要判断两个对象之间的关系是克隆还是引用,这时可以使用比较运算符“==”
和“===”
。两个等号是比较两个对象的内容,三个等号是比较对象的引用地址。
7.3.6 检测对象类型
instanceof操作符可以检测当前对象属于哪个类。一般格式为:ObjectName instanceof ClassName
7.3.7 魔术方法(__)
PHP中有很多以两个下画线开头的方法,如前面已经介绍过的__construct()
、__destruct( )
和__clone()
,这些方法被称为魔术方法。本节将会学习其他一些魔术方法。
PHP中保留了所有以“__”
开头的方法,所以只能使用PHP中已有的这些方法,不要自己创建。
__set()
和__get()
方法
这两个魔术方法的作用分别为:
当程序试图写入不存在或不可见的成员变量时,PHP就会执行__set()
方法。__set()
方法包含两个参数,分别表示变量名和变量值。两个参数不可省略。
当程序调用未定义或不可见的成员变量时,可以通过__get()
方法来读取变量值,__get()
方法有一个参数,表示要调用的变量名。
如果希望PHP调用这些魔术方法,那么首先必须在类中进行定义,否则PHP不会执行未定义的魔术方法。__call()
方法__call()
方法的作用是:当程序试图调用不存在或不可见的成员方法时,PHP会先调用方法来存储方法名及其参数。__call()
方法包含两个参数,即方法名和方法参数。其中,方法参数是以数组形式存在的。__sleep()
和__wakeup()
方法
PHP使用serialize()
函数可以实现序列化对象。就是将对象中的变量全部保存下来,对象中的类则只保存类名。
在使用serialize()
函数时,如果实例化对象包含__sleep()
方法,那么先执行__sleep()
方法。该方法可以清除对象并返回一个包含该对象中所有变量的数组。使用__sleep()
方法的目的是关闭对象可能具有的类似数据库连接等善后工作。unserialize()
函数可以重新还原被serialize()
函数序列化的对象,__wakeup()
方法则恢复在序列化中可能丢失的数据库连接及相关工作。__toString()
方法
魔术方法__toString()
的作用是:当使用echo或print输出对象时,将对象转换为字符串。__autoload()
方法
如果要在一个页面中引进很多个类,需要使用include_once()
或require_once()
函数逐个引入。PHP 5通过__autoload()
方法解决了这个问题。__autoload()
方法可以自动实例化需要使用的类。当程序要用到一个类,但该类还没有被实例化时,PHP 5将调用__autoload()
方法,在指定的路径下自动查找和该类的名称相同的文件。如果找到,程序则继续执行,否则,报告错误。
7.4 面向对象的应用——中文字符串的截取类
为了确保程序页面整洁美观,经常需要对输出的字符串进行截取。在截取英文字符串时,可以使用substr()函数来完成。但是当遇到中文字符串时,如果仍然使用substr()函数,就有可能出现乱码的情况。因为汉字是由两个字节组成的,所以当截取的字符数出现奇数时,就有可能将一个汉字拆分,从而导致输出不完整的汉字,也就是乱码。
第8章 字符串
8.1 字符串简介
字符串是指由零个或多个字符构成的一个集合,这里所说的字符主要包含以下几种类型:
数字类型,如1、2、3等。
字母类型,如a、b、c、d等。
特殊字符,如#、$、%、^、&等。
不可见字符,如\n (换行符)、\r (回车符)、\t(Tab字符)等。
其中,不可见字符是比较特殊的一组字符,用来控制字符串的格式化输出,在浏览器中不可见,只能看到字符串的输出结果。
8.2 引用字符串常量
在程序中有三种方法来引用字符串常量:使用单引号或双引号,以及使用从Unix shell衍生出来的heredoc技术。这些方法的不同之处在于它们是否识别特殊的转义序列(escape sequences,用于对字符进行编码)和是否进行变量解析。
一般的规则是,在必要时才使用强大的引用机制。在实际应用中,这意味着除非需要包含转义序列或替换变量,才使用双引号,否则应该使用单引号。如果要让一个字符串跨越多行,则使用heredoc技术。
8.3 单引号和双引号的区别
单引号中的内容,无论有无变量,都会被当作普通字符串原样输出。而双引号中的内容,要经过PHP语法分析器的解析。任何变量在双引号中都会被转换为值进行输出。
单引号字符串和双引号字符串在PHP中的处理是不同的。单引号字符串中的内容会被作为普通字符进行处理,而双引号字符串中的内容可以被解释并替换。
8.4 输出字符串
有四种方法可以向浏览器发送输出内容。
echo让你一次输出许多值。
而print()只能输出一个值。
printf()函数通过把值插入到模板中来建立格式化的字符串。
print_r()函数利于调试——以更容易读懂的方式打印数组、对象和其他东西的内容。
要把字符串放到PHP生成的HTML页面中,可以使用echo。echo的大部分行为看起来像函数,但其实echo是语言结构(language construct)。这意味着可以省略圆括号,所以下面两条语句是等价的:
1 | echo "printy"; |
可以将逗号作为分隔符来指定打印多项:echo "One","Two",Three";
输出结果为:OneTwoThree
8.5 字符串的连接符
在PHP中,半角句号“.”是字符串连接符,可以把两个或两个以上的字符串连接成一个字符串。
使用字符串连接符无法实现大量字符串的连接,所以PHP也允许程序员在双引号中直接包含字符串变量。
8.6 字符串操作
8.6.1 去除字符串的首尾空格和特殊字符
PHP提供了如下函数:
trim()函数用于去除字符串的首尾空格和特殊字符。
ltrim()函数用于去除字符串左边的空格和特殊字符。
rtrim()函数用于去除字符串右边的空格和特殊字符。
wordwrap()函数按照指定长度对字符串进行折行处理。
- trim()函数
trim()函数用于去除字符串的首尾空格和特殊字符,并返回去掉空格和特殊字符后的字符串。
语法格式如下:string trim(string str [,string charlist]);
参数str是要操作的字符串对象:参数charlist为可选参数,指定需要从字符串中删除哪些字符,如果不设置该参数,所有的可选字符都将被删除。 - ltrim()函数
ltrim()函数用于去除字符串左边的空格和特殊字符。
语法格式如下:string ltrim (string str [,string charlist]);
- rtrim()函数
rtrim()函数用于去除字符串右边的空格和特殊字符,语法格式如下:string rtrim(string str [,string charlist]);
- wordwrap()函数
wordwrap()函数按照指定长度对字符串进行折行处理,但可能会在行的开头留下空白字符。
语法格式如下:wordwrap(string,width,break,cut);
8.6.2 转义、还原字符串数据
转义、还原字符串的方法有两种:一种是手动转义、还原字符串数据:另一种是自动转义、还原字符串数据。
- 手动转义、还原字符串数据
字符串可以用单引号(‘)、双引号(‘’)、界定符(<<<) 3种方法定义,而指定一个字符串的最简单方法是用单引号(‘)括起来。当使用字符串时,很可能在字符串中存在这几种易于与PHP脚本混淆的字符,因此必须对这几种字符作转义处理,方法是在这些字符的前面使用转义符。
“\”是一个转义符,紧跟在“\”后面的第一个字符将变得没有意义或存在特殊含义。例如,“’”是字符串的定界符,写为“'”时就失去了定界符的意义,变成普通的单引号“’”。读者可以通过:echo ‘'‘;输出一个单引号,但转义符不会显示。 - 自动转义、还原字符串数据
要自动转义、还原字符串数据,可以应用PHP提供的addslashes()和stripslashes()函数来实现。
addslashes()函数用来为字符串加入反斜线“\”。string addslashes(string str);
stripslashes()函数用来将使用addslashes()函数转义后的字符串返回原样。string stripslashes(string str);
- addcslashes()函数
除上面介绍的方法外,还可以对要转义、还原的字符串进行一定范围的限制。PHP通过使用addcslashes()和stripcslashes()函数来实现对指定范围内的字符串进行自动转义和还原。
addcslashes()转义字符串中的字符,即在指定字符的前面加上反斜线“\”。
语法格式如下:wordwrap(string,width,break,cut);
- stripcslashes()函数
stripcslashes()函数用来对addcslashes()函数转义后的字符串进行还原。string stripcslashes(string str);
8.6.3 获取字符串的长度
- strlen()函数
在获取字符串的长度时,使用的是strlen()函数,下面重点讲解strlen()函数的语法及应用。
语法格式如下:int strlen(string str);
- strpos()函数
strpos()函数用于检索字符串中指定的字符或文本。
如果找到匹配,则会返回首个匹配的字符位置;如果未找到匹配,则返回FALSE。
8.6.4 截取字符串
在PHP中有一项非常重要的技术,就是截取指定字符串中指定长度的字符。对字符串截取时,可以采用PHP的预定义函数substr()来实现。
格式如下:string substr[string str,int start [, int length]);
8.6.5 比较字符串
在PHP中,对字符串之间进行比较的方法有很多种,第一种是使用strcmp()和strcasecmp()函数按字节进行比较,第二种是使用strnatcmp()函数按自然排序法进行比较,第三种是使用strncmp()函数从源字符串的指定位置开始比较。
- 按字节进行字符串的比较
按字节进行字符串比较的方法有两种,分别是利用strcmp()和strcasecmp()函数。
这两个函数的区别是:strcmp()函数区分字符的大小写,而strcasecmp()函数不区分字符的大小写。由于这两个函数的实现方法基本相同,这里只介绍strcmp()函数。
strcmp()函数用来对两个字符串按字节进行比较,语法格式如下:int strcmp(string str1,string str2);
- 按自然排序法进行字符串的比较
在PHP中,按照自然排序法进行字符串的比较是通过strnatcmp()函数来实现的。自然排序法比较的是字符串中的数字部分,将字符串中的数字按照大小进行比较。
语法格式如下:int strnatcmp(string str1,string str2);
- 从源字符串的指定位置开始比较
strncmp()函数用来比较字符串中的前n个字符。
语法格式如下:int strncmp(string str1,string str2,int len);
8.6.6 检索字符串
在PHP中,提供了很多用于检索字符串的函数,PHP也可以像Word那样实现对字符串的查找功能。
- strstr()函数:使用strstr()函数查找指定的关键字
可使用strstr()函数获取指定字符串在另一个字符串中首次出现的位置直到后者末尾的子字符串。如果执行成功,返回获取的子字符串(存在相匹配的字符);如果失败,返回false。
语法格式如下:string strstr(string haystack, string needle);
- substr_count()函数:使用substr_count()函数检索字符出现的次数
可使用substr_count()函数获取指定字符在字符串中出现的次数。
语法格式如下:int substr_count(string haystack,string needle);
参数haystack为指定的字符串。
参数needle为指定的字符。
8.6.7 替换字符串
通过字符串的替换技术可以实现对指定字符串中的指定字符进行替换。字符串的替换技术可以通过以下两个函数实现:str _ireplace()
函数和substr_replace()
函数。
str_ireplace()
函数str_ireplace()
函数:使用新的字符串(子串)替换原始字符串中指定要替换的字符串。
语法格式如下:mixed str_ireplace(mixed search,mixed replace,mixed subject [,int &count]);
将所有在参数subject中出现的参数search以参数replace取代,参数count表示替换字符串执行的次数。该函数不区分大小写。substr_replace()
函数substr_replace()
函数用于对指定字符串中的部分字符串进行替换。
语法格式如下:string substr_replace(string str,string repl,int start,[int length]);
8.6.8 格式化字符串
在PHP中,字符串的格式化方式有多种,按照格式化的类型可以分为字符串的格式化和数字字符串的格式化,数字字符串的格式化最为常用。number_format()
函数用来将数字字符串格式化。
语法格式如下:string number_format(float number[,int num_decimal_places] , [string dec_seperator,string thousands_ separator]);
8.6.9 分割字符串
字符串的分割是通过explode()函数实现的。
explode()函数按照指定的规则对字符串进行分割,返回值为数组。
语法格式如下:array explode(string separator,string str[,int limit]);
8.6.10 合成字符串
implode()函数可以将数组的内容组合成一个新的字符串。
语法格式如下: string implode(string glue,array pieces);
第9章 PHP与Web页面交互
9.1 PHP Web编程基础
客户端的浏览器要和服务器进行通信,必须遵守一定的规则或协议,WWW浏览器使用的是HTTP协议(HyperText Transfer Protocol,超文本传输协议)。浏览网页的过程其实就是一系列请求/响应的过程:用户使用浏览器浏览一个Web站点,首先通过网址向网络中的某台服务器发出请求,请求浏览某个页面;服务器在找到这个页面之后,在响应中返回相应页面的内容。
PHP与Web页面的交互过程
在浏览过程中,当用户需要与服务器进行交互时,可以通过客户端浏览器返回的HTML页面及嵌入HTML页面的PHP代码输入数据,输入的内容就会从客户端传送到服务器。PHP是一种运行在服务器端的语言,经过服务器端的PHP程序进行处理后,再将用户请求的信息返回给客户端浏览器。
9.2 Web表单
Web表单是一个通过使用HTML表单收集用户输入的不同类型数据,并且发送数据到服务器的工具,是浏览者和服务器互动的平台。
9.2.1 创建表单
使用<form>
标签,在HTML标记间插入<form>
和</form>
,即可创建一个表单。
表单的基本结构如下所示:
1 | <form name ="name" method ="method" action="url" enctype="value" target="target" id="id"> |
在使用Web表单时,必须为其指定行为属性action,以指定所提交数据的处理页面。
9.2.2 认识表单元素
表单(form)是由表单元素组成的,表单元素是指表单中的一些元素标签,常用的表单元素有以下几种:输入域标签<input>
、文本域标签<textarea>
、选择域标签<select>
和<option>
等,这些元素用于提供用户输入数据的可视化界面。
1 | <form> |
<input type='' ''>
标签共提供了十种类型的输入域
9.3 PHP与Web页面交互的基本方法
9.3.1 访问和获取Web表单数据
提交表单数据有两种方法:POST方法和GET方法。采用哪种方法提交数据由表单<form>
的method
属性值决定。
PHP通过两个预定义的变量$_GET
和$_POST
获取用户提交的表单数据,$_GET
和$_POST
都是PHP的自动全局变量,可以直接在PHP程序中使用。
变量$_GET
是由表单数据组成的数组变量,数组$_GET[]
中保存了由表单的GET方法提交的数据,数组的“键”就是表单元素的名称。这就意味着,通过表单元素的名称(name属性的值)就可以获取表单元素的值。例如,表单中有一个文本框,名为“User_name”,PHP程序就可以通过数组$_GET['User_name']
获取该文本框中用户输入的值。
变量$_POST
同样是数组变量,用于获取及保存表单以POST方法提交的数据,用法和变量$_GET
类似。
9.3.2 Web表单数据的有效性验证
在实际开发应用中,PHP程序往往要对用户输入和提交的数据作有效性验证,以保证程序执行的安全和数据的完整、有效。
为了方便对常见的数据类型进行验证,PHP语言提供了empty()、is_numeric()、is_null()等函数,以进一步对表单提交的数据进行验证。
empty()函数:用于检测变量是否具有空值,空值包括空字符串、0、null或false。如果具有空值,返回true;否则返回false。
is_numeric()函数:用于检测变量是否为数字或数字字符串,如果是,返回true;否则返回false。
is_null()函数:用于检测变量是否为null,只有在变量被定义且值为null时,才返回true,否则返回false。
9.3.3 Web表单的安全性验证
在互联网程序设计中,凡是用户提交的数据,默认它们是不安全的,需要进行验证或过滤,以保证已有的数据不会遭到破坏,或者服务器不被入侵。例如,通过Web表单提交一个段表单标签,或是浏览器可以执行的JavaScript代码,此时用户提交的数据可以改变网页的正常处理方式,甚至篡改服务器数据,这必然会给网站的安全带来风险。
为了解决网页的数据安全问题,PHP提供了strip_tags()和htmlentities()函数,这两个函数都可以过滤表单数据。
strip_tags()函数:用于去除字符串中的HTML标记和PHP标记。
htmlentities()函数:用于将字符转换为 HTML 实体,即把HTML标记和PHP标记转换成字符,以文本的形式输出。
9.3.4 PHP文件上传处理
在PHP与Web页面的交互中,经常会遇到从客户端浏览器上传文件到服务器端以及文件后续处理的问题。文件上传和数据上传类似,常使用POST方法。
在文件上传程序中,要将表单的enctype属性设置为“multipart/form-data”,代码如下:
1 | <form name ="name" enctype="multipart/form-data" method ="method" action="url" target="target" > |
9.4 PHP全局变量
9.4.1 全局变量$_SERVER
在PHP Web页面交互程序中,经常使用全局变量$_SERVER
,它是由Web服务器创建的信息数组,用于存放HTTP报头信息、路径信息以及和Web服务器相关的信息。对于不同的Web服务器,$_SERVER
中包含的变量值和变量个数也会有所不同。
9.4.2 全局变量$_GET
在PHP Web页面交互程序中,Web表单通常使用POST或GET方法提交表单数据。对于通过GET方法提交的数据,使用$_GET
变量来获取。在 PHP 中,预定义的 $_GET
变量是一个数组,用于收集来自method=”GET” 的表单中的值。从带有 GET 方法的表单发送的信息,对任何人都是可见的(会显示在浏览器的地址栏中),并且对发送信息的量也有限制。
9.4.3 全局变量$_POST
在PHP中,全局变量 $_POST
用于收集使用表单方法 method=”POST”传送的数据。$_POST
变量是一个数组,内容是 POST 方法发送的变量名称和值,表单域的name值会自动成为 $_POST
数组中的 ID 键。
使用 POST 方法发送的数据,对任何人都是不可见的(不会显示在浏览器的地址栏中),并且对发送信息的量也没有限制。
默认情况下,POST 方法所发送数据量的最大值为 8 MB,如果需要更大的数据传送量,可以通过设置PHP默认配置文件 php.ini 中的 post_max_size选项进行更改。
9.4.4 全局变量$_SESSION
在PHP Web页面交互程序中,会经常用到session技术。session是一种服务器端技术,所谓session,就是“会话”,是指从用户访问页面开始,到断开与网站的连接、结束访问的中间过程。在这个过程中,Web服务器会为访问者创建一个私有的session文件,用来记录访问者的各种信息,这些用户信息就保存在全局变量$_SESSION
中,应用程序中的所有页面都可以使用它。
session技术弥补了HTTP协议的局限:HTTP协议被认为是无状态协议,无法获得用户的浏览状态,在服务器端完成响应之后,服务器就失去了与浏览器的联系,所以服务器无法全程感知客户端的用户状态;而通过全局变量$_SESSION
记录用户的相关信息,使得服务器可以随时获取用户访问信息,保持了用户身份的连续性。
session的工作机制是:为每个访问者创建唯一的 id (UID),并基于UID来存储变量。其工作过程由相应的session函数完成。
在使用session之前,首先必须使用session_start()函数启动session。启动成功后,Web服务器会声明一个全局变量$_SESSION
,该全局变量也是一个全局变量数组$’_SESSION[]‘
,将用户的各种数据保存在数组$_SESSION[]
中。需要读取session中存储的数据时,也就是从数组$_SESSION[]
中读取。
第10章 会话管理
10.1 用cookie保存页面状态
10.1.1 cookie的组成
cookie可以用来在用户的浏览器中存储少量数据(不多于4KB)。之后,每当浏览器请求这个网站的某个页面时,所有保存在cookie中的数据就会自动发送给服务器。这意味着,从我们把数据发送到浏览器这一刻起,这些数据将始终可以自动地供脚本程序使用。
可以为cookie的持续时间规定一个固定值,从几秒到几年都行,也可以把cookie设置为每当浏览器关闭时它就失效。大多数浏览器最多可以为每个站点保存30个cookie。
cookie是作为HTTP头的一部分由服务器发送给浏览器的。下面这个例子说明了如何在HTTP头中创建cookie:
1 | Set-Cookie: fontSize=3; expires=Tuesday, 29-Nov-2017 17:53:08 GMT; path=/; |
10.1.2 在PHP中设置cookie
如何在PHP脚本中把一个cookie发送给浏览器呢?虽然可以直接把一个cookie设置为一个Set-Cookie:HTTP头(利用PHP的header()函数),但是实际上还有更简单的方法。
PHP提供了一个内部函数setcookie(),这个函数可以发送一个合适的HTTP头,用来在浏览器中创建cookie。
下面这个例子用setcookie()函数创建了一个cookie,它保存了用户选择的字号:setcookie( "fontSize",10, time()+3600, "/", ".example.com",false, true );
10.1.3 在脚本中访问cookie
在PHP脚本中访问cookie非常容易:只需要从$_COOKIE
超全局数组中读取相应的值即可。我们可以想象到,这个关联数组保存了当前请求的浏览器所发送的一系列cookie值,并且以cookie名作为键。
要显示前一个例子中创建的名为pageViews的cookie,需要用到下面的命令:echo $_COOKIE["pageViews"]; // 显示 "8"
只有在浏览器发出下一次请求之时,我们才可以在脚本中通过$_COOKIE
访问新创建的cookie。这是因为,第一次运行脚本时,只是把cookie发送给浏览器。在浏览器向服务器发出下一个请求之前,没有把这个cookie返回给服务器。例如:
1 | setcookie( "pageViews", 7, 0, "/", "", false, true ); |
10.1.4 删除cookie
为了安全考虑,我们用完cookie之后,需要删除cookie的值。要删除存储在浏览器中的某个cookie,可以命令浏览器删除它。要删除一个cookie,需要用cookie名和任意一个值(如空字符串)调用setcookie()函数,并将任意一个已过去的时间传递给expires参数,这样将会立刻终止浏览器中的cookie,并确保它已被删除。
此外,要把创建cookie时使用的path、domain和其他字段的值传递给这个函数,以确保删除真正需要删除的cookie:setcookie( "fontSize", "", time() - 3600, "/", ".example.com", false, true );
10.2 用PHP会话存储数据
虽然cookie是存储数据的一种常用方法,但是这种方法也存在几个问题。
首先,这种方法不安全。与表单数据和查询字符串一样,黑客们能够很容易地将自己的数据插入到cookie中,这些数据可能会破坏或影响应用程序或组件的安全性。
其次,虽然用cookie可以存储比较多的数据,但是每当浏览器对服务器的URL发出请求时,都需要传递这个Web站点的所有cookie数据。假如我们保存了10个cookie,每个cookie的大小为4KB,那么用户每次访问一个页面时,都要上传40KB的数据。
上述两个问题都可以用PHP会话来解决。PHP会话不是将数据存储在浏览器中,而是将数据存储在服务器上,并且为数据建立一个会话ID(Session ID,SID)字符串。
PHP引擎会把包含SID的cookie发送给浏览器,由浏览器来存储这个cookie。然后,当浏览器请求Web站点的某个URL时,它会把这个SID cookie发回给服务器,使PHP脚本能够根据发回的cookie读取会话数据,从而允许脚本访问这些数据。
PHP生成的SID是唯一的、随机的,而且几乎是不可能猜中的,因此黑客们很难访问或修改会话数据。更重要的是,由于会话数据存储在服务器上,因此不需要在每次浏览器请求时都发送。所以与cookie方法相比,会话可以存储更多的数据。
默认时,PHP会把每个会话的数据存储在服务器上的一个临时文件中。这个临时文件的位置由PHP配置文件中的session.save_path指令决定,用下面的语句可以显示这个值:echo ini_get( "session.save_path" );
10.2.1 创建会话
在PHP中创建会话相当容易。为了在脚本中创建会话,只需要调用session_start()函数即可。如果这是一个新会话,这个函数会为该会话建立唯一的SID,并把它当作一个cookie(默认情况下,取名为PHPSESSID)发送给浏览器。然而,假如存在一个会话,而且浏览器已经把PHPSESSID cookie发送给了服务器,session_start()就会使用这个现有的会话:session_start();
10.2.2 读取和写入会话数据
在PHP脚本中处理会话数据也很容易。我们把所有会话数据以键和值的形式存储在$_SESSION[]
超全局数组中。因此,我们可以用下面的方法存储用户的名:$_SESSION["firstName"] = "张三";
然后可以显示这个用户的名——不管是在同一页面请求中,还是在后面的页面请求中,如下所示:echo( $_SESSION["firstName"] );
10.2.3 撤销会话
默认情况下,当用户退出浏览器时,PHP会自动删除会话,这是因为我们把PHPSESSID cookie的expires字段设置为0。然而,有时我们可能希望立刻撤销一个会话。要撤销一个会话,需要调用PHP内部函数session_destroy():session_destroy();
然而我们需要注意,这仅仅删除了保存在磁盘上的会话数据,而保存在$_SESSION
数组中的数据要等到脚本运行结束时才会被删除。因此,为了保证全部会话数据都被删除,必须重新初始化$_SESSION
数组:
1 | $_SESSION = array(); |