最好的语言!
资料
基本语法
<?php code ?>
如果是纯 php 代码时, 建议忽略最后php>
, 防止最后的空白进行输出<? code ?>
配置为--enable-short-tags
<?php if(){ ?> if-content <?php } else { ?> else-content <?php } ?> // same <?php if(): ?> if-content <?php else: ?> else-content <?php endif ?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
- 必须写分号 `;`
## 类型
标量类型
- boolean
- string
- integer
- float
复合类型
- array
- object
- callable
特殊类型
- resource
- NULL
### special function
- `gettype($var)` 返回 `"integer"` / `"float"` / `"string"` / `"boolean"`
- `is_$type()` 返回 boolean, 如 `is_string($x)`
### boolean
- `true` / `false` 不区分大小写
- 一切空值都是 false, 空字符串 / `0` / 空 array ...
- 使用 `(boolean)"1"/ (bool)"1"` 进行强制转换
### string
- `''` 单引号字符不进行 expand, 和 SHELL 一样
- `""` 双引号字符串会进行 expand, 类似 js 模板字符串
- Here doc
```php
$s = <<<END
hello
here doc
END;
$s = <<<"END"
hello
here doc
END;Now doc, Here doc + single quote 标识不进行 expand variales 操作
1
2
3
4$s = <<<'END'
hello
here doc
END;
float / integer
- 常规表示
0b
/0
/0x
前缀表示 二进制/八进制/十六进制 - integer 只有 signed integer, 与平台有关, 32 位系统上是 32 bit signed
array
- = JsArray + JsObject
- key 可以是 int / string
- 使用
array()
/[]
创建.key => val
object
- 使用
$val = (object) $other;
将一个值强转为 object 类型 - 将会创建一个内置类*
stdClass
* 的实例
NULL
NULL
类型的值只能是NULL
值NULL
值不区分大小写,null
is OK
- 这些情况会是
NULL
值- 被赋值为 NULL。
- 尚未被赋值。
- 被 unset()。
callable
- 使用 string 类型标识一个函数
- 使用
array('ClassName', 'staticMethodName')
来表示一个方法 - 使用
array($instance, 'instanceMethodName')
来表示一个方法
变量
全局变量
- 出了函数作用域之后的变量, 类似 Python
- 使用
global $a, $b;
声明使用全局变量 - 全局变量实际上是存储在
$GLOBALS
这个 array 中
超全局变量
- 是全局变量
- 在任意作用域都可以直接访问, 不需要使用
global $var
声明
包含
常量
使用
define
/const
来声明常量, 常量值只能是标量类型 / resource 类型// http://php.net/manual/zh/function.define.php bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
- `get_defined_constants()` 返回已定义的常量 array
### 魔术常量
类似 Node.js `__dirname` / `__filename`
- `__LINE__` 当前行号
- `__FILE__` 当前文件完整路径, realpath when symlink
- `__DIR__` 当前文件所在文件夹, realpath when symlink
- `__FUNCTION__` / `__METHOD__` 当前函数名 / 方法名
- `__CLASS__` / `__TRAIT__` / `__NAMESPACE__` 当前类, Trait , namespace 名
## 表达式
### 运算符
- `===` / `==` 与 JavaScript 一致, `===` 表示类型和值都相等
- `!=` = `<>`
- `a <=> b`
- `a > b` -> `>0`
- `a = b` -> `=0`
- `a < b` -> `<0`
- `$a ?? $b ?? $c` 返回第一个不为 `NULL` 的值
- 逻辑运算符 `&&` & `and` / `||` & `or` 都可以
- `$var instanceof Class`
#### 错误控制运算符 `@`
> 当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。
#### 执行 Shell 运算符 ``
> 会被当成 shell 命令来执行, 和 `shell_exec()` 函数效果一致
> 在 **安全模式** 和 **关闭`shell_exec`** 时不起作用
## 控制流
### `foreach`
```php
foreach($arr as $item) {
}
等同于 JavaScript 中
1 | for (let $item of $arr) { |
include
/ require
include
失败会导致E_WARNING
级别的错误require
失败会导致E_COMPILE_ERROR
级别的错误, 会导致脚本处理终止
include
处理顺序
- 有路径, 按照路径查找,
include_path
会被忽略- 绝对路径
/
开头 - 相对路径
./
or../
- 绝对路径
- 只有文件名时, 按顺序查找
- 按照
include_path
寻找, 类似 Java classpath - 脚本所在目录
- 当前工作目录
pwd
- 按照
include 返回值
- 成功时返回 1
- 失败返回 false, 并发出警告
1 | if(include 'path.php') { |
函数 x
- PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然。
- PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。
全局作用域实例
bar
在foo
调用的时候定义的, 但是也具有全局作用域
1 |
|
可变数量参数
1 | function fn_name(...$args) { |
默认参数
1 | function makecoffee($type = "cappuccino") { |
可变函数
如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数
如
1 | function hello_world(){ |
匿名函数
- PHP 会自动把此种表达式转换成内置类 Closure 的对象实例
- 把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号. 相当于 JavaScript 函数表达式.
闭包使用外部变量
- 需要使用
use 提前声明
1 |
|
类与对象
属性和方法
var $prop
/public $prop
static $staticProp
function method()
static function staticFunctionName()
规则
- 属性
- 必须使用
public
/private
/protected
或var
限定 - 使用
var
声明, 为 public - 使用
$this -> prop
引用, 注意没有$
- 必须使用
- 静态属性
- 不能使用
var
声明 - 使用
self::$staticProp
引用, 注意有$
- 不能使用
- 方法
- 可使用
public
/private
/protected
限定, 默认为public
- 可使用
static
1 | class Test{ |
- 使用
ClassName::staticFunctionName()
调用 - 在类中使用
self::staticFunctionName()
使用self
指代自己parent::staticFunctionName()
使用parent
指代父类
const
类常量
1 | class Test{ |
- 在定义和使用常量的时候不需要使用
$
符号。
- 不能使用范围限定符, 默认就是 public
new
new ClassName()
new "ClassName"()
new $cls()
abstract
- 定义为抽象的类不能被实例化。
- 任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
- 被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
- 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;
- 这些方法的访问控制必须和父类中一样(或者更为宽松)。
interface
- 接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。
trait
同 mixin
- 定义和
class
一致 - 使用,
use MyTrait;
重载
PHP 所提供的”重载”(overloading)是指动态地”创建”类属性和方法。
http://php.net/manual/zh/language.oop5.overloading.php
final
- 如果父类中的方法被声明为 final,则子类无法覆盖该方法。
- 如果一个类被声明为 final,则不能被继承。
clone
/ __clone
$obj2 = clone $obj1
会去调用 obj1 的
__clone
方法, 类如果不实现__clone
方法的话, 默认为赋值浅克隆. 对于属性值是引用类型的属性, 在实现 __clone 方法的时候, 需要调用 clone 再次复制子属性.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Object{
var $prop = 1;
}
class Test{
var $o = new Object();
function __clone(){
$this -> o = clone $this -> o;
}
}
$t1 = new Test;
$t2 = clone $t1;
// 这时 $t1 / $t2 的 `-> o -> prop` 就不是同一个值
命名空间
- 使用
namespace Level1\Level2;
定义命名空间 - 使用
use Level1\Level2;
使用命名空间 - 使用
use Level1\Level2 as L2;
使用命名空间别名
名称解析规则
http://php.net/manual/zh/language.namespaces.rules.php
错误处理
生成器
引用
注意在函数调用时没有引用符号——只有函数定义中有。
以下内容可以通过引用传递:
变量,例如 foo($a)
New 语句,例如 foo(new foobar())
从函数中返回的引用,例如:
1
2
3
4
5
6
7
8
function &bar(){
$a = 5;
return $a;
}
foo(bar());