3月18号被优化掉了,失业中,思来想去还是要继续写代码,一直都是实际业务开发,PHP基础忘掉了很多,边看书边整理,做个记录。
PHP变量作用域
-
local:局部变量,函数内部定义的变量;
-
global:全局变量,可在任何地方使用;
-
static:静态变量,又分为静态局部变量和静态全局全量:
- 静态局部变量:一种特殊的局部变量,值不会随着函数的调用和退出发生变化,只能在函数内部使用;不管其所在的函数是否被调用,其都会一直存在,但不能使用它,只有当调用其所在的函数时,才可以继续使用;
- 静态全局变量:声明全局变量时前面加上static关键字,就变成静态全局变量;
-
parameter:参数作用域,通过调用代码将值传递给函数的局部变量;
全局变量:
// 全局变量
$a = 1;
$b = 2;
function my_func()
{
// 使用全局变量前 要加上global关键字
global $a, $b;
echo $a + $b;
}
my_func();
静态变量:可以在任何可以声明的地方声明,在之后的运行中,始终保持最后一次声明时的赋值;静态变量并非不能改变其值,其拥有的值是可变的,而是始终保持最新的赋值;静态,指的是变量的值不会随着函数的调用和退出而发生变化。
function testStatic()
{
static $val = 1;
// 即便此处的条件不成立 也可以声明静态变量
if(1 == 2){
static $val = 2;
}
echo $val;
$val++;
echo "<br/>";
}
testStatic(); //output 2
testStatic(); //output 3
testStatic(); //output 4
传值和引用的区别
传值:默认情况下,函数参数通过值传递,即使在函数内部改变参数的值,也不会改变函数外部的参数值;
传引用:在函数的参数前面添加符号&
,表示函数参数必须为引用地址,不是一个具体的值,在函数内部对该参数所做的操作会影响函数外部的参数值;且当参数是引用传递时,不可直接给参数值,而应该传递变量名,否则报错;
优缺点:按值传递时,PHP必须复制值,对于大型的字符串或对象来说,这个操作会付出比较大的代价,按引用传递则不需要复制值,对于性能提高有好处。
// 传值 函数strtolower
$str = "ABC";
echo $str;// ABC
echo strtolower($str);// abc
echo $str;// ABC 调用strtolower函数 但没有改变变量$str的值
// 传引用 函数sort
$arr = [1,3,2];
var_dump($arr);// [1,3,2]
sort($arr);
var_dump($arr);// 调用sort函数后 数组$arr的值被改变为[1,2,3] 因为sort函数的参数是传引用
// 引用传递的参数 不可以直接给值 而应该传递参数名
sort([1,3,2]);// 执行报错 Only variables can be passed by reference 即:只有变量可以通过引用传递
数组排序函数
- array_multisort() 对多个数组或多维数组排序
- arsort() 按键值降序排序
- asort() 按键值升序排序
- krsort() 按键名降序排序
- ksort() 按键名升序排序
- natcasesort() 用”自然排序“算法对数组进行不区分大小写字母的排序
- natsort() 用”自然排序“算法对数组排序
- rsort() 对数值数组进行降序排序
- sort() 对数值数组进行升序排序
- uasrot() 使用用户自定义的比较函数对数组中的键值进行排序
- uksort() 使用用户自定义的比较函数对数组中的键名进行排序
- usort() 使用用户自定义的函数对数组进行排序
使用final修饰的类和方法代表什么意思
final修饰的类不能被继承,final修饰的方法不能被重写。
PHP中如果比较两个对象
- ==:比较两个对象的值是否相等
- ===:比较两个对象的的类型和值是否完全相等
NULL的三种情况
- 直接赋值NULL
- 未定义变量
- unset销毁后的变量
常用字符串函数
- implode() join() 将数组中的元素组合为字符串
- explode() 将字符串拆分为数组
- strrev() 反转字符串
- trim() 移除字符串两侧的空白字符或其它预定义字符
- ltrim() 移除字符串左侧的空白字符或其它预定义字符
- rtrim() 移除字符串右侧的空白字符或其他预定义字符
- strstr() 搜索字符串在另一个字符串中的第一次出现
常用数组函数
- array_keys() 返回包含指定数组中所有键名的一个新数组
- array_values() 返回包含指定数组中所有键值的一个新数组
- array_diff() 比较两个数组的值 并返回差集
- array_megre() 把两个数组合并为一个数组
- array_shift() 删除数组中的第一个元素,并返回删除的元素
- array_unshift() 用于向数组插入新元素,新数组的值将被插入到数组的开头
- array_pop() 删除数组中的最后一个元素,并返回删除的元素
PHP常见设计模式
- 工厂模式
- 单例模式
- 适配器模式
- 观察者模式
- 策略模式
- 注册树模式
include include_once require require_once区别
- include:读入指定文件并执行里面的代码;发生错误时,生成一个E_WARING,脚本可以继续执行;
- require:读入指定文件,并把
require
自身替换为读入的内容;发生错误时,生成一个E_COMPILE_ERROR,脚本停止执行; - include_once:与include_once相同,区别是如果当前文件已包含被读入的文件,则不会再次读入;
- require_once:与require相同,区别是PHP会检查文件是否已包含,是则不再包含;
include和require都是语句结构,不是函数,因此可以不加括号,直接加引号来包含文件:
include "01_var.php";
require "01_var.php";
实质区别:
- include:每次执行文件时都要读取和评估;
- require:文件只处理一次(require本身会被替换为包含的文件内容);
也就是说,如果是需要反复执行的代码,使用require效率更高;如果每次执行代码时需要读取不同的文件,则使用include。
使用场景:
- 希望代码在出错时继续执行,则使用include;
- 复杂框架的PHP代码中,使用require,以提高应用程序的安全性和完整性;比如ThinkPHP框架的入口文件index.php引入核心代码使用的是require;
- require通常放在PHP脚本最前面,php脚本执行前,先读取require包含的文件内容,使之成为待执行脚本的一部分;
- include通常在流程控制中使用,php脚本执行时读到include包含的文件,才读入内容;
PHP常用缓存技术
-
全页面静态化缓存:将页面全部生成html静态页面,用户直接访问静态页面,不走php服务器解析流程;
ob_start() ******要运行的代码******* $content = ob_get_contents(); ****将缓存内容写入html文件***** ob_end_clean();
-
页面部分缓存:将页面中不经常改变的部分进行静态缓存,经常变化的部分不缓存,最后组装在一起显示;可以使用ob_get_contents实现,或者通过ESI之类的页面片段缓存策略;
-
数据缓存:缓存数据的一种方式,比如商城中的某个商品,通过商品ID查询详情时,将店铺信息、商品信息等数据缓存到php文件中,以商品ID作为唯一标识,后续查询该商品ID的信息时,直接调用缓存的php文件,不需要访问数据库;
-
查询缓存:根据查询语句来缓存,将查询到的数据缓存到文件中,后续遇到相同的查询语句,直接从文件中获取数据,不再访问数据库;
-
按内容变更进行缓存:并非独立的缓存技术,需要结合前几种缓存技术使用;当数据库内容被修改时,随即更新对应的缓存文件;
-
内存式缓存:比如Redis或Memcached,Memcached就是一个高性能的分布式内存缓存服务器,通过缓存数据库查询结果,减少数据库访问次数,以提高动态web应用的响应速度;
-
apache缓存模块:安装apache时激活mod_cache模块;
-
php APC缓存扩展:使用php的APC缓存扩展;
-
Opcode缓存:比如php自带的opcache缓存扩展;php代码的执行流程大致是,php代码被解析为Tokens,然后编译为Opcode码,最后执行Opcode码,返回结果;故可以对相同的php文件,第一次运行时缓存其Opcode码,下次再执行此php文件,直接找到缓存的Opcode码,直接执行,跳过中间步骤,以提高运行效率;
简述PHP-FPM
PHP FastCGI Process Manager:PHP Fast CGI进程管理器,用来管理PHP进程池来处理来自web服务器的http请求,其中的master进程负责与web服务器通信,接收http请求,将请求转发给worker进程进行处理,worker进程负责执行PHP代码,执行完成后,将执行结果返回给web服务器,再由web服务器将结果发送给客户端。
PHP垃圾回收机制
待补充
PHP session原理
session工作机制
session是为弥补HTTP协议无状态的不足,session为每个访客创建一个唯一的id(UID),并基于这个UID在服务器端保存用户数据。UID存储在cookie中,或通过URL进行传导。
session工作原理
调用session_start()函数,写入变量,PHP往服务器目录(由php.ini文件中的session.save_path指定)写入一个文件,并向客户端的cookie写入一个名为PHPSESSID的变量:
session_start();
$_SESSION['name'] = 'phper';
$_SESSION['blog'] = 'startphp.cn';
此时sess_sessid文件中的内容,是序列化后数据:
a:2:{s:4:"name";s:5:"phper";s:4:"blog";s:11:"startphp.cn";}
客户端的cookie:服务器端自动写入了一个cookie,内容是一个字符串,就是sessid,sessid对应具体的访客,当这个用户进行后续访问操作时,浏览器会带上这个cookie,PHP获取到sessid后,去对应文件夹找到session文件,读取用户数据。
session回收机制
session目录下存在多个文件,这些文件不会永久存在,PHP提供了过期回收机制。
在php.ini中通过session.gc_maxlifetime
为session设置了生存时间(默认1440s),如果session文件的最后更新时间超过了生存时间,这个session文件被认为已过期,在下一次session回收时会被删除。
至于下一次session回收什么时候发生,需要参考PHP的请求次数,也就是当PHP脚本被请求N次后触发一次回收机制,通过以下两个参数控制:
// php7.3.4默认配置
session.gc_probability = 1
session.gc_divisor = 1000
意思是,每1000次PHP请求就有一次回收发生,概率是gc_probability/gc_divisor。
前文说到调用session_start()函数时,会向客户端发送一个名为PHPSESSID的cookie,这个cookie的生命周期由php.ini中的以下参数控制:
// 默认0 即浏览器关闭后失效
session.cookie_lifetime = 0
禁用cookie
前文说到session依赖cookie,如果浏览器禁用了cookie,就只能通过URL传递sessid。
PHP可以在cookie被禁用时自动通过GET方式传递sessid,前提是php.ini的以下配置为1:
session.use_trans_sid = 1
这样就算禁用了cookie,在页面跳转时,PHP会自动在URL上添加sessid参数,例如:
nextpage.php?SESSIONID=2bd170b3f86523f1b1b60b55ffde0f66