日常总结

数组

list 和 compact

  1. <?php
  2. $city = "San Francisco";
  3. $state = "CA";
  4. $event = "SIGGRAPH";
  5. $location_vars = array(
  6. "city",
  7. "state"
  8. );
  9. $result = compact("event", "nothing_here", "location_vars");
  10. print_r($result);
  11. echo "<br/><br/>";
  12. $result = compact("event", "nothing_here", $location_vars);
  13. print_r($result);
  14. ?>

概述

PHP 脚本主要用于以下三个领域

服务端脚本

这是 PHP 最传统,也是最主要的目标领域。开展这项工作需要具备以下三点:PHP 解析器(CGI 或者服务器模块)、web 服务器和 web 浏览器。需要在运行 web 服务器时,安装并配置 PHP,然后,可以用 web 浏览器来访问 PHP 程序的输出,即浏览服务端的 PHP 页面。如果只是实验 PHP 编程,所有的这些都可以运行在自己家里的电脑中。

命令行脚本

可以编写一段 PHP 脚本,并且不需要任何服务器或者浏览器来运行它。通过这种方式,仅仅只需要 PHP 解析器来执行。这种用法对于依赖 cron(Unix 或者 Linux 环境)或者 Task Scheduler(Windows 环境)的日常运行的脚本来说是理想的选择。这些脚本也可以用来处理简单的文本。

编写桌面应用程序

对于有着图形界面的桌面应用程序来说,PHP 或许不是一种最好的语言,但是如果用户非常精通 PHP,并且希望在客户端应用程序中使用 PHP 的一些高级特性,可以利用 PHP-GTK 来编写这些程序。用这种方法,还可以编写跨平台的应用程序。PHP-GTK 是 PHP 的一个扩展,在通常发布的 PHP 包中并不包含它。

安装与配置

安装前需要考虑的事项
Unix 系统下的安装
Mac OS X 系统下的安装
Windows 系统下的安装
云计算平台上的安装

FastCGI 进程管理器(FPM)

php-fpm配置

PHP配置详解

修改配置的三种方式

php.ini文件
Apache的httpd.conf和.htaccess文件
在执行脚本中

配置指令作用域

  1. PHP_INI_PERDIR 指令可以在php.ini、httpd.conf或.htaccess文件中修改

  2. PHP_INI_SYSTEM 指令可以在php.ini、httpd.conf中修改

  3. PHP_INI_USER 指令可以在用户脚本中修改

  4. PHP_INI_ALL 指令可以在任何地方修改

PHP的配置指令详解

php.ini是PHP的全局配置文件

语言选项

  • engine

  • zend.zel_compatibility_mode = ON | OFF

PECL 扩展库安装
还有问题?
运行时配置

基本语法

PHP标记

如果文件内容是纯 PHP 代码,最好在文件末尾删除 PHP 结束标记。这可以避免在 PHP 结束标记之后万一意外加入了空格或者换行符,会导致 PHP 开始输出这些空白,而脚本中此时并无输出的意图。

文件末尾的 PHP 代码段结束标记可以不要,有些情况下当使用 include 或者 require 时省略掉会更好些,这样不期望的空白符就不会出现在文件末尾,之后仍然可以输出响应标头。在使用输出缓冲时也很便利,就不会看到由包含文件生成的不期望的空白符

向浏览器输出数据

  • print(),输出字符串,是一种语言结构

  • echo(),可输出多个字符串,echo比print更快,因为print会返回1而echo不返回

  • printf(string format [,mixed args]),可以用后边的参数替换string中的占位符

  • stringf() 函数和printf()类似

  • print_r() 易于理解的格式打印变量

  • var_dump() 此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构

  • var_export() 输出或返回一个变量的字符串表示

类型

标量数据类型

  1. Boolean 布尔类型

  2. Integer 整型

  3. Float 浮点型

  4. String 字符串

$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

echo $str;

复合数据类型

  • Array 数组

  • Object 对象

  • Callback / Callable 类型

两种特殊类型

  • Resource 资源类型

  • NULL

本文档中使用的伪类型与变量

伪类型

mixed(混合类型)
number(数字类型)
callback(回调类型,又称为 callable)
array|object(数组 | 对象类型)
void (无类型)

伪变量

$…

类型转换的判别

gettype()可以判断数据类型 array boolean double integer object resource string unknown type
settype()

  • is_array()

  • is_bool()

  • is_float()

  • is_integer()

  • is_null()

  • is_numeric()

  • is_object()

  • is_scalar()

  • is_string()

强制转换

(int), (integer) - 转换为整形 integer
(bool), (boolean) - 转换为布尔类型 boolean
(float), (double), (real) - 转换为浮点型 float
(string) - 转换为字符串 string
(array) - 转换为数组 array
(object) - 转换为对象 object
(unset) - 转换为 NULL (PHP 5)

变量

PHP 中的变量用一个美元符号后面跟变量名来表示。变量名是区分大小写的

变量范围(作用域)

局部变量
函数参数
全局变量
静态变量

预定义变量

PHP 提供了大量的预定义变量。由于许多变量依赖于运行的服务器的版本和设置,及其它因素,所以并没有详细的说明文档。一些预定义变量在 PHP 以命令行形式运行时并不生效。

  1. 超全局变量 — 超全局变量是在全部作用域中始终可用的内置变量

  2. $GLOBALS — 引用全局作用域中可用的全部变量

  3. $_SERVER — 服务器和执行环境信息

  4. $_GET — HTTP GET 变量

  5. $_POST — HTTP POST 变量

  6. $_FILES — HTTP 文件上传变量

  7. $_REQUEST — HTTP Request 变量

  8. $_SESSION — Session 变量

  9. $_ENV — 环境变量

  10. $_COOKIE — HTTP Cookies

  11. $php_errormsg — 前一个错误信息(比如使用了错误抑制符)

  12. $HTTP_RAW_POST_DATA — 原生POST数据

  13. $http_response_header — HTTP 响应头,当使用HTTP 包装器时,$http_response_header 将会被 HTTP 响应头信息填充

$_SERVER

$_SERVER[‘HTTP_REFERER’] 引导用户到达当前页面的来源url
$_SERVER[‘REMOTE_ADDR’] 客户端IP地址
$_SERVER[‘REQUEST_URI’] URL的路径部分
$_SERVER[‘HTTP_USER_AGENT’] 客户的用户代理,客户端浏览器和操作系统相关信息

可变变量

一个可变变量获取了一个普通变量的值作为这个可变变量的变量名
当写下 $$a[1] 时,解析器需要知道是想要 $a[1] 作为一个变量呢,还是想要 $$a 作为一个变量并取出该变量中索引为 [1] 的值。解决此问题的语法是,对第一种情况用 ${$a[1]},对第二种情况用 ${$a}[1]。

变量相关函数内置函数

  • boolval — 获取变量的布尔值

  • debug_zval_dump — Dumps a string representation of an internal zend value to output

  • doubleval — floatval 的别名

  • empty — 检查一个变量是否为空

  • floatval — 获取变量的浮点值

  • get_defined_vars — 返回由所有已定义变量所组成的数组

  • get_resource_type — 返回资源(resource)类型

  • gettype — 获取变量的类型

  • import_request_variables — 将 GET/POST/Cookie 变量导入到全局作用域中

  • intval — 获取变量的整数值

  • is_array — 检测变量是否是数组

  • is_bool — 检测变量是否是布尔型

  • is_callable — 检测参数是否为合法的可调用结构

  • is_countable — Verify that the contents of a variable is a countable value

  • is_double — is_float 的别名

  • is_float — 检测变量是否是浮点型

  • is_int — 检测变量是否是整数

  • is_integer — is_int 的别名

  • is_iterable — Verify that the contents of a variable is an iterable value

  • is_long — is_int 的别名

  • is_null — 检测变量是否为 NULL

  • is_numeric — 检测变量是否为数字或数字字符串

  • is_object — 检测变量是否是一个对象

  • is_real — is_float 的别名

  • is_resource — 检测变量是否为资源类型

  • is_scalar — 检测变量是否是一个标量

  • is_string — 检测变量是否是字符串

  • isset — 检测变量是否已设置并且非 NULL

  • print_r — 以易于理解的格式打印变量。

  • serialize — 产生一个可存储的值的表示

  • settype — 设置变量的类型

  • strval — 获取变量的字符串值

  • unserialize — 从已存储的表示中创建 PHP 的值

  • unset — 释放给定的变量

  • var_dump — 打印变量的相关信息

  • var_export — 输出或返回一个变量的字符串表示

常量

在脚本执行期间该值不能改变
传统上常量标识符总是大写的
用法:define(“NAME”,”value”);

表达式

任何有值得东西都是表达式

运算符

-$a 取反 $a 的负值
$a + $b 加法 $a 和 $b 的和
$a - $b 减法 $a 和 $b 的差
$a * $b 乘法 $a 和 $b 的积。
$a / $b 除法 $a 除以 $b 的商。
$a % $b 取模 $a 除以 $b 的余数。
$a ** $b Exponentiation
  • 运算符优先级

  • 算术运算符

  • 赋值运算符

  • 位运算符

  • 比较运算

  • 错误控制运算符 @

  • 执行运算符 使用反引号运算符“```”的效果与函数 shell_exec() 相同,反引号运算符在激活了安全模式或者关闭了 shell_exec() 时是无效的

  • 递增/递减运算符

  • 逻辑运算符 或 or 、||and 、 &&not 、 ! 异或 xor 两值有一为true 但不同时是

  • 字符串运算符 .

  • 数组运算符 +=====!=!==<>

$a + $b 联合 $a 和 $b 的联合,运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略
$a == $b 相等 如果 $a 和 $b 具有相同的键/值对则为 TRUE
$a === $b 全等 如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 TRUE
$a != $b 不等 如果 $a 不等于 $b 则为 TRUE
$a <> $b 不等 如果 $a 不等于 $b 则为 TRUE
$a !== $b 不全等 如果 $a 不全等于 $b 则为 TRUE

注意:对比 array_merege() 用法与+ 运算,array_merge() 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。 如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。 如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引

  • 类型运算符 instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例

流程控制

if
else
elseif/else if
流程控制的替代语法
PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch。替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。
while
do-while
for

for (expr1; expr2; expr3)
    statement

第一个表达式(expr1)在循环开始前无条件求值(并执行)一次。
expr2 在每次循环开始前求值。如果值为 TRUE,则继续循环,执行嵌套的循环语句。如果值为 FALSE,则终止循环
expr3 在每次循环之后被求值(并执行)。

foreach

foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:

foreach (array_expression as $value)
    statement
foreach (array_expression as $key => $value)
    statement

break

break 结束当前 for,foreach,while,do-while 或者 switch 结构的执行。

break 可以接受一个可选的数字参数来决定跳出几重循环
$i = 0;
while (++$i) {
    switch ($i) {
    case 5:
        echo "At 5<br />\n";
        break 1;  /* 只退出 switch. */
    case 10:
        echo "At 10; quitting<br />\n";
        break 2;  /* 退出 switch 和 while 循环 */
    default:
        break;
    }
}

continue
continue 在循环结构用用来跳过本次循环中剩余的代码并在条件求值为真时开始执行下一次循环。
注意在 PHP 中 switch 语句被认为是可以使用 continue 的一种循环结构。
continue 接受一个可选的数字参数来决定跳过几重循环到循环结尾。默认值是 1,即跳到当前循环末尾。
switch
switch/case 作的是松散比较
declare
return
如果当前脚本文件是被 include 的或者 require 的,则控制交回调用文件。此外,如果当前脚本是被 include 的,则 return 的值会被当作 include 调用的返回值。如果在主脚本文件中调用 return,则脚本中止运行。如果当前脚本文件是在 php.ini 中的配置选项 auto_prepend_file 或者 auto_append_file 所指定的,则此脚本文件中止运行
require
require 在出错时产生 E_COMPILE_ERROR 级别的错误。
include
如果找不到文件,导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行
require_once
include_once
PHP 会检查该文件是否已经被包含过,如果是则不会再次包含
goto
goto 操作符可以用来跳转到程序中的另一位置。该目标位置可以用目标名称加上冒号来标记,而跳转指令是 goto 之后接上目标位置的标记。PHP 中的 goto 有一定限制,目标位置只能位于同一个文件和作用域,也就是说无法跳出一个函数或类方法,也无法跳入到另一个函数。也无法跳入到任何循环或者 switch 结构中。可以跳出循环或者 switch,通常的用法是用 goto 代替多层的 break

函数

内置函数

一些函数需要和特定地 PHP 扩展模块一起编译,否则在使用它们的时候就会得到一个致命的“未定义函数”错误,但是可以用 bool function_exists ( string $function_name ) 确认有没有这个函数或者 get_extension_funcs() 有没有相关扩展

几百个函数,参看列表

用户自定义函数

function name(…$params) {
}

按值传递参数

& 按引用传递参数

默认参数值

默认参数值必须位于参数列表末尾并且为常数表达式,当然也可以有好几个默认参数

可变数量的参数列表

在 PHP 5.6 及以上的版本中,由 … 语法实现;在 PHP 5.5 及更早版本中,使用函数 func_num_args(),func_get_arg(),和 func_get_args()

使用类型提示

返回值

用list() 构造接收函数返回的多个值

function retrieveUserProfile () {
    $user[] = "Jason gilmore";
    $user[] = "jason@example.com";
    $user[] = "English";
}
list($name, $email, $lang) = retrieveUserProfile();

echo "Name:{$name}, email: {$email}, language:{$lang}"

可变函数

这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它

递归函数

匿名函数

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值
闭包可以从父作用域中继承变量。 任何此类变量都应该用 use 语言结构传递进去。 PHP 7.1 起,不能传入此类变量: superglobals、 $this 或者和参数重名

数组

创建数组
输出数组
测试数组
添加或删除数组元素
定位数组元素
遍历数组
确定数组大小和元素唯一性
排序
合并、拆分、结合和分解

面向对象

基本概念

class
new
extends

类的自动加载

在 PHP 5 中,已经不再需要这样了。 spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类
自动加载不可用于 PHP 的 CLI 交互模式

构造函数和析构函数

void __construct ([ mixed $args [, $... ]] )

void __destruct ( void )

访问控制(可见性)

对象继承

范围解析操作符 (::)

范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法

Static(静态)关键字

声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)
用静态方式调用一个非静态方法会导致一个 E_STRICT 级别的错误

抽象类

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法

对象接口

要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称
接口也可以继承,通过使用 extends 操作符

Trait

自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承

trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World';
    }
}

class MyHelloWorld {
    use Hello, World;
    public function sayExclamationMark() {
        echo '!';
    }
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();

程序输出
Hello world!

序列化

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

为了能够unserialize()一个对象,这个对象的类必须已经定义过。如果序列化类A的一个对象,将会返回一个跟类A相关,而且包含了对象所有变量值的字符串。 如果要想在另外一个文件中解序列化一个对象,这个对象的类必须在解序列化之前定义,可以通过包含一个定义该类的文件或使用函数spl_autoload_register()来实现。

命名空间

错误与异常

生成器
引用的解释
预定义变量
预定义异常
预定义接口
上下文(Context)选项和参数
支持的协议和封装协议

两篇参考文章
https://laravel-china.org/articles/5657/laravel-exceptions-exception-and-error-handling
https://blog.csdn.net/hguisu/article/details/7464977

安全

简介
总则
以 CGI 模式安装时
以 Apache 模块安装时
会话(Session)安全
文件系统安全
数据库安全
错误报告
使用 Register Globals
用户提交的数据
魔术引号
隐藏 PHP
保持更新
特点
用 PHP 进行 HTTP 认证

会话技术

Cookie
会话
处理 XForms

注意点

  1. setCookie 必须在所有输出前设置,否则设置不了;
  2. 一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。

文件操作

文件上传处理
使用远程文件
连接处理
数据库持久连接
安全模式
PHP 的命令行模式
垃圾回收机制
DTrace 动态跟踪
函数参考
影响 PHP 行为的扩展
音频格式操作
身份认证服务
针对命令行的扩展
压缩与归档扩展
信用卡处理
加密扩展
数据库扩展
日期与时间相关扩展
文件系统相关扩展
国际化与字符编码支持
图像生成和处理
邮件相关扩展
数学扩展
非文本内容的 MIME 输出
进程控制扩展
其它基本扩展
其它服务
搜索引擎扩展
针对服务器的扩展
Session 扩展
文本处理
变量与类型相关扩展
Web 服务
Windows 专用扩展
XML 操作
图形用户界面(GUI) 扩展
PHP 核心:骇客指南
序言
内存管理
变量的使用
函数的编写
类和对象的使用
资源的使用
INI 设置的使用
流的使用
“counter” 扩展 - 一个连续的实例
PHP 5 构建系统
扩展的结构
PDO 驱动
扩展相关 FAQ
Zend Engine 2 API 参考
Zend Engine 2 操作码列表
Zend Engine 1
FAQ — FAQ:常见问题
一般信息
邮件列表
获取 PHP
数据库问题
安装 — 安装常见问题
编译问题
使用 PHP
密码散列 — 密码散列安全
PHP 和 HTML
PHP 和 COM
其他问题
附录
PHP 及其相关工程的历史
从PHP 7.1.x 移植到 PHP 7.2.x
从PHP 7.0.x 移植到 PHP 7.1.x
从PHP 5.6.x 移植到 PHP 7.0.x
从PHP 5.5.x 移植到 PHP 5.6.x
从 PHP 5.4.x 迁移到 PHP 5.5.x
从 PHP 5.3.X 迁移到 PHP 5.4.X
从 PHP 5.2.x 移植到 PHP 5.3.x
Migrating from PHP 5.1.x to PHP 5.2.x
Migrating from PHP 5.0.x to PHP 5.1.x
从 PHP 4 移植到 PHP 5
PHP 的调试
配置选项
php.ini 配置
扩展库列表/归类
函数别名列表
保留字列表
资源类型列表
可用过滤器列表
所支持的套接字传输器(Socket Transports)列表
PHP 类型比较表
解析器代号列表
用户空间命名指南
关于本手册
Creative Commons Attribution 3.0
索引
更新日志

参考资料

PHP官方手册
PHP The Right Way
awesome-php
https://github.com/appzcoder/30-seconds-of-php-code