PHP基础
一些题
https://www.php.cn/toutiao-415599.html
get和post区别
HTTP协议中的两种发送请求的方法
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET请求只能进行url提交数据,而POST支持多种提交数据方式。常见的四种提交数据方式
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- 理论上GET请求在URL中传送的参数是没有长度限制的,因为get传值是通过url提交数据,那么get可传的参数量就和url的长度有关系。而实际上url不存在参数上限的问题,http协议规范没有对url长度进行限制,这个限制是浏览器和服务器对它的限制。
- 理论上讲post请求参数也是没有限制的,因为http协议没有进行大小限制,起限制能力的是服务器处理程序的处理能力。
- 对参数的数据类型,GET只接受string,而POST可以是Integer 、Boolean、String 、集合。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
post传值方式
- application/x-www-form-urlencoded
- application/json
- 500: 该状态码表明服务器端在执行请求时发生了错误。也有可能是web应用存在bug或某些临时故障
- 503: 该状态码表明服务器暂时处于超负载或正在停机维护,现在无法处理请求
- 502: 表示作为网关或代理角色的服务器,从上游服务器(如tomcat、php-fpm)中接收到的响应是无效的
- 400: 服务器端无法理解客户端发送的请求,请求报文中可能存在语法错误
- 401: 该状态码表示发送的请求没有通过HTTP认证(BASIC认证,DIGEST认证)的认证信息。(没通过验证)
- 403: 不允许访问那个资源。该状态码表明对请求资源的访问被服务器拒绝了。(权限,未授权IP等)(通过验证了但是没有访问的权限)
- 404: 服务器上没有请求的资源。路径错误等
- 304: 当访问资源出现304访问的情况下其实就是先在本地缓存了访问的资源。
- 302: 资源的URI已临时定位到其他位置了,姑且算你已经知道了这个情况了。临时性重定向
- 301: 永久重定向
$_SERVER
- $_SERVER[‘HTTP_HOST’] //请求头。
- $_SERVER[‘REMOTE_PORT’] //端口。
- $_SERVER[‘SERVER_NAME’] //服务器主机的名称。
- $_SERVER[‘HTTP_ACCEPT’] //当前请求的 Accept: 头部的内容。
- $_SERVER[‘HTTP_ACCEPT_CHARSET’] //当前请求的 Accept-Charset: 头部的内容。
- $_SERVER[‘HTTP_ACCEPT_ENCODING’] //当前请求的 Accept-Encoding: 头部的内容
- $_SERVER[‘HTTP_CONNECTION’] //当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。
- $_SERVER[‘HTTP_HOST’] //当前请求的 Host: 头部的内容。
- $_SERVER[‘HTTP_REFERER’] //链接到当前页面的前一页面的 URL 地址。
- $_SERVER[‘HTTPS’]//如果通过https访问,则被设为一个非空的值(on),否则返回off
- $_SERVER[‘SERVER_PORT’] //服务器所使用的端口
- HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
REMOTE_ADDR
获取用户IP地址
Linux给文件加权限
chmod -R 777 文件夹;给文件加所有文件添加权限
如果给所有人添加可执行权限:chmod a+x 文件名;
如果给文件所有者添加可执行权限:chmod u+x 文件名;
如果给所在组添加可执行权限:chmod g+x 文件名;
如果给所在组以外的人添加可执行权限:chmod o+x 文件名;
Linux知道具体报错信息查询log日志
cat log.txt | grep ‘ERROR’ -A 5
意思是,在log.txt文件中,查找ERROR字符,并显示ERROR所在行的之后5行
- 缓存(热点数据)
由于redis访问速度块、支持的数据类型比较丰富,所以redis很适合用来存储热点数据,另外结合expire,我们可以设置过期时间然后再进行缓存更新操作 - 队列(秒杀活动)
由于redis有list push和list pop这样的命令,所以能够很方便的执行队列操作。 - 限时业务的运用
redis中可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景
redis和memcached相同点
在内存中存储数据,防止高并发影响数据库性能,减少数据库压力,并提高查询速度
redis和memcached区别
- 支持数据类型不同
Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储; - 内存管理机制不同
在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = agelog(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。*这种特性使得Redis可以保持超过其机器本身内存大小的数据。 - 是否支持数据持久化
存储数据安全—memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);
灾难恢复—memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复; - 应用场景不同
Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。
PHP中require和include的区别
相同点:
1. 都用来包含文件
2. include_once 和 require_once 都会先检查文件是否包含过
不同点:
1. require 包含文件时,若文件存在错误,程序会中断,显示致命错误。
2. include 包含文件时,若文件存在错误,程序会发出警告,继续执行。
3. require 一般用于程序开头
4. include 一般用于程序流程中
PHP常见字符串命令
- strtoupper() //将字符串转为大写
- strtolower() //将字符串转为小写
- ucfirst() //如果字符串第一个字符是字符,将其转为大写
- ucwords() //将字符串的每个单词的首字母大写
- strtok() //函数把字符串分割为更小的字符串
- substr() //函数返回字符串的一部分
- strlen() //函数测试字符串的长度
- strcmp() //比较两个字符串,如果相等,函数返回0
- strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串
PHP数组去重函数
array_unique()
PHP获取二维数组某一列的全部数据
- 遍历数组
- 或者使用array_column($arr, ‘name’)
SQL中where,limit,groupby,having和orderby查询的先后顺序,为什么
- 执行where xx对全表数据做筛选,返回第1个结果集。
- 针对第1个结果集使用group by分组,返回第2个结果集。
- 针对第2个结果集中的每1组数据执行select xx,有几组就执行几次,返回第3个结果集。
- 针对第3个结集执行having xx进行筛选,返回第4个结果集。
- 针对第4个结果集排序,得到结果集5。
- 对第5个结果集,使用limit。
常用的魔术方法
- 构造函数
__construct()
和析构函数__desctruct(
)分别在对象创建和销毁时被调用。对象被“销毁”是指不存在任何对该对象的引用,比如引用该对象的变量被删除(unset)、重新赋值或脚本执行结束,都会调用析构函数。 __tostring()
方法:对象被当作string(字符串)使用时(如echo $obj),此方法自动调用,此方法中须返回(return)一个字符串__call()
,在对象中调用一个不可访问方法时调用__callStatic()
,用静态方式中调用一个不可访问方法时调用__get()
:读取不可访问或不存在属性的值时,__get()
会被调用__set()
:在给不可访问属性赋值时调用__isset()
:当对不可访问属性调用isset()或empty()时调用__unset()
:当对不可访问的属性调用unset()时调用__clone
克隆:当对一个对象使用clone关键字时,该魔术方法会被调用。在这个魔术方法里,我们可以实现任何子对象的克隆
单利模式用到了哪些魔术方法__construct()
和__clone
PHP中的 抽象类(abstract class)和 接口(interface)PHP中的 抽象类(abstract class)和 接口(interface)
$this和salf和parents的用法
self | this | |
---|---|---|
能在静态函数里使用 | 是 | 否 |
方法 | self:: | $this-> (注意:PHP > 5.3 允许由 $this 使用静态变量,用 $this::$foo。 $this->foo 将仍然没有被定义,如果 $foo 是一个静态变量.) |
需要一个实例对象 | 否 | 是 |
数据库常用的搜索引擎
InnoDB: 如果要提供提交、回滚、崩溃恢复能力的事物安全(ACID兼容)能力,并要求实现并发控制
MyISAM: 如果数据表读多写少,则MyISAM引擎能提供较高的处理效率
MEMORY: 如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果
ARCHIVE: 如果只有INSERT和SELECT操作,可以选择Archive,Archive支持高并发的插入操作,但是本身不是事务安全的。Archive非常适合存储归档数据,如记录日志信息可以使用Archive
数据库搜索引擎区别
- InnoDB 支持事务,MyISAM 不支持事务。
- InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
- InnoDB 是聚簇索引,MyISAM 是非聚簇索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
- InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
- InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
数据库事务
四大属性: 原子性,隔离性,持久性,一致性
- 描述
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。 - 解决方案
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
设置热点数据永远不过期。
遍历目录文件
public function bianli1($dir)
{
$files = array();
if($head = opendir($dir))
{
while(($file = readdir($head)) !== false)
{
if($file != ".." && $file!=".")
{
if(is_dir($file))
{
$files[$file]=bianli1($dir.'/'.$file);
}
else
{
$files[]=$file;
}
}
}
}
closedir($head);
return $files;
}
时间复杂度和空间复杂度有什么关系
快速排序
通过设置一个初始中间值,来将需要排序的数组分成3部分,小于中间值的左边,中间值,大于中间值的右边,继续递归用相同的方式来排序左边和右边,最后合并数组
冒泡排序
$arr=array(1,43,54,62,21,66,32,78,36,76,39);
function getpao($arr)
{
$len=count($arr);
//设置一个空数组 用来接收冒出来的泡
//该层循环控制 需要冒泡的轮数
for($i=1;$i<$len;$i++)
{ //该层循环用来控制每轮 冒出一个数 需要比较的次数
for($k=0;$k<$len-$i;$k++)
{
if($arr[$k]>$arr[$k+1])
{
$tmp=$arr[$k+1];
$arr[$k+1]=$arr[$k];
$arr[$k]=$tmp;
}
}
}
return $arr;
}
二分法查找
二分查找法需要数组是一个有序的数组。
<?php
function binarySearch($num, $arr) {
$start = 0;
$end = count($arr);
$mid = floor(($start+$end)/2);
while ($start<$end-1) {
if ($num == $arr[$mid]) {
return $mid;
} elseif ($num < $arr[$mid]) {
$end = $mid;
$mid = floor(($start+$end)/2);
} else {
$start = $mid;
$mid = floor(($start+$end)/2);
}
}
return false;
}
$arr = [1,2,3,4,5,6,7,8,9,10];
$result = binarySearch(7,$arr);
print_r($result);
git解决冲突办法
git查看冲突
git 撤销
- 丢弃工作区的修改,用命令git checkout .
- git add到暂存区后,撤销
第一步: git reset HEAD <file>,就回到了场景1
第二步: git checkout . - commit后push前撤销
第一步:git log 找到想要撤销的commit_id
第二步:git reset —hard commit_id (撤销commit提交以及代码的修改)
或git reset commit_id (仅仅撤销本地仓库的commit提交,代码不变) - push后撤销
第一步: git log //查看对应的id
第二步: git reset –hard a1edaeb37a5 //对应想要回撤处的提交id
第三步: git push origin -f //强制 push 到远程仓库 - 只修改commit注释
git commit —amend -m ‘备注信息’ 即可覆盖上次信息合并为一次提交
项目中技术难点
推荐文章: