PHP 学习笔记

1、PHP简史

  1. PHP最初是作为工具包出现。
  2. 1996发布2.0版本,可以访问数据库,还可以把PHP代码嵌入到HTML页面中。
  3. PHP3.0重写了代码,具有强大的可扩展性。
  4. 2000发布4.0,出现Zend引擎,性能提升近10倍。
  5. 2004发布5.0,引入了面向对象、类型提示和异常处理。
  6. 2005年发起的6.0最终被取消,但命名空间、匿名函数、闭包等特性加入到5.x版本。
  7. 2016发布PHP7,性能提升一倍。
  8. 2020发布PHP8,引入JIT 编译、联合类型、属性等,性能提升一倍。

2、PHP程序执行方式

PHP为解释执行,首先将源码编译为opcode指令集合,后PHP虚拟机解释执行opcode。PHP8又引入了JIT编译。PHP程序执行由Zend引擎完成,底层是C语言实现。
在这里插入图片描述
PHP 源码目录:

  • sapi:输入输出层的抽象,常用实现有:
    • apache2handler,编译生成动态链接库,当有http请求到Apache时,根据配置调用此动态链接库,执行PHP代码;
    • cgi-fcgi,编译生成支持CGI协议的可执行程序,通过CGI协议把请求传给CGI进程,执行代码将结果返回,退出进程;
    • fpm-fcgi,FastCGI进程管理器,若使用Nginx,Nginx按照FastCGI协议把请求交给php-fpm进程处理;
    • cli,命令行交互接口;
  • Zend:Zend引擎核心代码,包括编译器、解释器、内存管理、底层数据结构等
  • main:SAPI层和Zend层的黏合剂,解析参数,调用PHP脚本
  • ext:PHP扩展,比如定义了array、str、pdo等函数
  • TSRM:线程安全资源管理器,为每个线程提供独立的全局变量副本

PHP虚拟机架构
在这里插入图片描述
PHP内存管理
在这里插入图片描述

  • 采用了内存池,用于提高内存分配、释放的性能
  • 借鉴了jemalloc和tcmalloc这两个成熟的内存管理方案
  • 垃圾回收为引用计数法

3、变量

PHP变量为弱类型,类型在运行时动态决定,底层由结构体zval表示,占16字节。

$an_int = 12; // 变量声明
  • 四种标量类型
    bool(布尔型):值为 true 或 false
    int(整型)
    float(浮点型,也称作 double)
    string(字符串):二进制安全
  • 四种复合类型
    array(数组):实现为HashTable
    object(对象):属性通过HashTable实现
    callable(可调用):支持简单函数、类的方法、实现__invoke方法的对象
    iterable(可迭代):配合foreach使用,支持array 、Traversable、yield
  • 两种特殊类型
    resource(资源):文件句柄、Socket连接、数据库连接等
    NULL(无类型)
var_dump()  // 表达式的值和类型
gettype() // 表达式的类型
is_int()  // is_type函数,检查类型
$foo = (int) $bar; // 强制类型转换

引用

$a =& $b; // 意味着 $a 和 $b 指向了同一个变量

变量的作用域
局部变量、全局变量、静态变量、常量

智能字符串
smart_str,用于频繁对一个字符串进行扩容修改。

4、数组 array

数组的语义

  • PHP数组是一个字典,存储key-value对,键是整型或字符串。
  • PHP数组是有序的,有序指插入顺序。

数组的实现为Hashtable:
在这里插入图片描述

  • bucket:存储单元,存储key、value、h值等
  • slot:一个slot下可以有多个bucket
  • 冲突解决:链地址法,即将同一个slot中的bucket通过链表连接起来
  • hash1函数:字符串key计算出一个h值,h值为数字,数字key返回数字本身
  • hash2函数:将h值映射为slot的索引值
  • h和key:“h”代表数字key,“key”代表字符串key

数组的数据结构

  • 所有bucket都分配在连续的数组内存中,冲突解决是记录下一个bucket在数组中的索引
  • bucket分为未使用、有效、无效三种。插入操作永远在下一个未使用bucket上进行。删除操作将有效标记为无效。当无效bucket较多时,对整个bucket数组进行rehash操作,一部分有效和无效bucket会被释放出来,重新变为未使用bucket。

packed array 和 hash array

$a = array(1,2,3); // packed array
$b = array('x'=>1, 'y'=>2, 'z'=>3); // hash array
  • packed array
    数组的key即为bucket数组的下标
  • hash array
    数组的key通过hash函数得到索引,再通过索引数组得到所在bucket
    在这里插入图片描述

5、面向对象

class SimpleClass extends BaseClass {
	// 常量
	const CONST_VALUE = 'A constant value';
    // 声明属性
    public $var = 'a default value';
    // 构造方法
    function __construct() {
        parent::__construct();
        print "In SubClass constructor\n";
    }
    // 声明方法
    public function displayVar() {
        echo $this->var;
    }
}
$obj = new SimpleClass();
echo $obj::CONST_VALUE;
echo SimpleClass::CONST_VALUE;

可见性:public(默认)、protected、private
static:静态属性/方法,可以直接通过类访问
final:final方法无法被子类覆盖,final类不能被继承

抽象类和接口

abstract class AbstractClass {
    abstract protected function getValue();
}
interface iTemplate {
    public function setVariable($name, $var);
}

trait
组合的代码复用方式;
当前类的成员覆盖 trait 的方法,而 trait 覆盖被继承的方法;

trait ezcReflectionReturnInfo {
    function getReturnType() { /*1*/ }
    function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
    use ezcReflectionReturnInfo;
    /* ... */
}
// 使用多个trait
class Aliased_Talker {
    use A, B {
        B::smallTalk insteadof A; // 同名时使用B的smallTalk 
        B::bigTalk as talk; // B的bigTalk起一个别名
    }
}

匿名类

var_dump(new class(10) {
    private $num;
    public function __construct($num) {
        $this->num = $num;
    }
});

重载
PHP的重载指动态地创建类属性和方法。
重载方法必须声明为 public。

// 以下“不可访问”指未定义或不可见

// 在给不可访问属性赋值时,__set() 会被调用。
public __set ( string $name , mixed $value ) : void
// 读取不可访问属性的值时,__get() 会被调用。
public __get ( string $name ) : mixed
// 当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
public __isset ( string $name ) : bool
// 当对不可访问属性调用 unset() 时,__unset() 会被调用。
public __unset ( string $name ) : void
// 在对象中调用一个不可访问方法时,__call() 会被调用。
public __call ( string $name , array $arguments ) : mixed
// 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用。
public static __callStatic ( string $name , array $arguments ) : mixed

遍历属性

// 遍历所有可见属性
foreach($objA as $key => $value) {
    print "$key => $value\n";
}

也可以实现 Iterator 接口或 IteratorAggregate 接口,自行决定如何遍历。

魔术方法
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法。

自定义方法建议不要以 __ 为前缀。

对象复制

// 浅拷贝
$copy_of_object = clone $object;

对象比较

  • $o1 == $o2 两个对象的属性和属性值都相等,且是同一个类的实例
  • $o1 === $o2 指向同一个对象

后期静态绑定
用于在继承范围内引用静态调用的类。

class A {
    public static function foo() {
        static::who();
    }
    public static function who() {
        echo __CLASS__." ";
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }
    public static function who() {
        echo __CLASS__." ";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__." ";
    }
}

C::test(); // 输出 A C C

协变与逆变
协变使子类比父类方法能返回更具体的类型; 逆变使子类比父类方法参数类型能接受更模糊的类型。

6、CGI (Common Gateway Interface)

CGI 是一种数据协议,用来规范web服务器传输到php解释器中的数据类型以及数据格式,包括URL、查询字符串、POST数据、HTTP header等。CGI程序可以由不同语言实现。

PHP Web服务处理请求过程:
在这里插入图片描述
CGI 与 Servlet 的区别:

  • Servlet 处于服务器进程中,它通过多线程方式运行其 service 方法,一个实例可以服务于多个请求,并且其实例一般不会销毁
  • CGI 对每个请求都产生新的进程,服务完成后就销毁,称作 fork-and-execute 模式,效率上低于servlet

因为CGI效率低,但对配置很敏感,通常被用在开发和调试阶段。

FastCGI
FastCGI 是 CGI 的增强版本,主要用来提高CGI程序性能,同样可以由不同语言实现。工作方式:

  1. Web Server启动同时,加载FastCGI进程管理器(nginx的php-fpm或微软IIS的ISAPI或Apache的Module)
  2. FastCGI进程管理器读取php.ini配置文件,对自身进行初始化,启动多个CGI解释器进程(php-cgi),等待来自Web Server的连接
  3. 当Web Server接收到客户端请求时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server会将相关环境变量和标准输入发送到FastCGI子进程php-cgi进行处理
  4. 在Linux中,nginx加php-fpm是最主流的使用方式

PHP SAPI(Server Application Programimg Interface):

  • 相当于PHP外部环境的代理器。PHP可以应用在终端上(CLI SAPI),也可以应用在Web服务器中(CGI SAPI)。
  • 底层实现为 _sapi_module_struct。

Nginx + PHP-FPM 模式

  • FPM(FastCGI Process Manager)是一个FastCGI进程管理器,可以有效控制内存和进程,支持平滑重启PHP及重载PHP配置。
  • FPM是多进程的服务,其中有一个master进程(做管理工作)和多个worker进程(处理数据请求)。
  • 执行过程主要分为5大阶段,分别是模块初始化、请求初始化、执行、请求关闭和模块关闭。由于FPM是常驻内存的进程,所以其模块初始化只做一次,便进入循环,而模块关闭在进程退出时也只做一次。

PHP-FPM 进程有三种设置方式:

  • static:固定数量的worker进程
  • dynamic:设置一个范围,worker进程数动态变化
  • ondemand:worker进程闲置了指定秒数后就会被杀掉

通信示意图:
在这里插入图片描述
在这里插入图片描述

7、控制语句

条件语句
if…elseif…else 、 switch…case

循环语句
while 、 do…while 、 for 、 foreach
break 、 continue

代替语法
把左花括号 { 换成冒号 :,把右花括号 } 分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;

if ($a == 5):
    echo "a equals 5";
else:
    echo "a is not 5";
endif;

goto:

for($i=0,$j=50; $i<100; $i++) {
	while($j--) {
		if($j==17) goto end; 
	}  
}
echo "i = $i";
end:
echo 'j hit 17';

match:

$expressionResult = match ($condition) {
    1, 2 => foo(),
    3, 4 => bar(),
    default => baz(),
};

8、函数

生成器
yeild

function makeRange($length) {
    for($i = 0; $i < $length; $i++) {
        yield $i;
    }
}
foreach (makeRange(100) as $i) {
    echo $i . PHP_EOL;
}

闭包(匿名)函数

$message = 'hello';

// 继承 $message
$example = function () use ($message) {
    var_dump($message);
};
$example();

箭头函数
匿名函数和箭头函数都是 Closure 类的实现

$y = 1;
// 可以自动捕获变量的值
$fn1 = fn($x) => $x + $y;

var_export($fn1(3));

Callable 类型

// An example callback function
function my_callback_function() {
    echo 'hello world!';
}

// An example callback method
class MyClass {
    static function myCallbackMethod() {
        echo 'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function'); 

// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod')); 

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

PHP 8 新特性

目录 HTML 1 小知识点 1 表格 3 Frameset 5 Form/input 8 Map 11 HTML5 12 canvas 12 HTML5废除的标签 13 XML 15 基本语法 15 DTD校验 16 在xml文件中引入dtd文件的两种方式 17 DTD元素修饰符 17 元素属性列表说明 17 实体定义分两种 18 使用php对xml文件进行操作 19 CSS 23 margin 26 element 28 box 29 position 31 apache 34 PHP 36 数据类型 36 一.双引号与单引号 36 二.运算符 36 三.字符串拼接 36 四.类型运算符 36 五.switch语句 36 六.全局变量 37 七.预定义变量 37 函数 39 数组 40 一.用字符串做下标 40 二.使用小数作为key将,自动截断小数部分 40 四.删除数组元素 40 六.二维数组。 40 类 41 一.重载 41 二.覆盖 41 三.抽象类 41 四.final 42 五.const 42 时间 42 一.输出日期 42 错误处理 43 一.自定义错误处理函数 43 二.触发器 43 三.异常处理 43 四.设置顶级异常处理器 45 防盗链 45 HTTP 46 经过一定时间跳转到指定页面 46 不让浏览器缓存 46 cookie 47 session 47 php.ini中关于sessioncookie的配置说明 50 文件操作 51 文件读取 51 文件下载 52 文件上传 53 写入文件 54 拷贝文件 54 文件文件夹的创建删除 55 画图 56 画饼状图 56 案例一:投票柱状统计图 57 案例二:验证码 59 GD库 60 PHP数据库 64 mysql扩展库 64 一.创建一张用户表 64 二.查询数据库中的表 64 三.增删改查类 65 四.数据库操作函数 66 mysqli扩展库 69 一.查询数据库中的表 69 二.释放资源的方式 69 三.增删该查类 69 四.预编译 70 mail 71 ZendFramework 73 快速体验 73 修改数据 74 增加数据 74 查询数据 74 memcached 76 telnet操作 76 php中使用memcached 78 把session数据放入memcache中 79 小知识点 80
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值