PHP面试基础题

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。

使用场景:

  1. 希望代码在出错时继续执行,则使用include;
  2. 复杂框架的PHP代码中,使用require,以提高应用程序的安全性和完整性;比如ThinkPHP框架的入口文件index.php引入核心代码使用的是require;
  3. require通常放在PHP脚本最前面,php脚本执行前,先读取require包含的文件内容,使之成为待执行脚本的一部分;
  4. 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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值