PHP 基础知识

02. February 2018 PHP 0

1.Get和Post区别

①Get幂等,Post不幂等(幂等是指同一个请求方法执行多次和仅执行一次的效果完全相同)。

②Get是从服务器上获取数据,post是向服务器传送数据。

Get适合传送小数据,IE下url长度限制2083(2K+35),Http协议规范没有对url长度限制,不同浏览器对url长度限制不尽相同,Chrome这种主流浏览器,正常使用最好在4096(4k)以下,有人     统计最高可到7675,具体数据不知。

Post没有长度限制,但受服务器配置限制,如post_max_size,也受脚本执行时间,内存等限制。

除此之外,还有

PUT:在服务器更新资源(客户端提供改变后的完整资源)

PATCH:在服务器更新资源(客户端提供改变的属性)

DELETE:从服务器删除资源

HEAD:获取资源的元数据

OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的

③Get 只接受ASCII字符,URL对所有人可见。Post没有限制,通过请求header请求。当然抓包的话,可以看到。

④Get请求方式,浏览器把http header 和data一起发送出去,服务器相应200,返回数据。

Post请求,浏览器先发送header,服务器相应100 (Continue 初始的请求已经接受,客户应当继续发送请求的其余部分),浏览器再发送data,服务器相应200,返回数据。

2.Cookie 和 Session 的区别和关系

①cookie存在浏览器,根据请求的路径自动发送(包括Ajax请求),请求在服务器端进行处理。

session是存在服务器的,用于区分会话和不同用户的访问,session可存在内存,数据库,文件中。session id存在cookie中,服务器端根据客户端发过来的cookie中的session id来判断保持会话。

②cookie 数量和大小有限制,不同浏览器对同一网站下最大cookie数不相同,每个域名cookie限制为20个不在正确,最少也是30.大小限制4K。超出后内容将丢失。Session 无此限制。

3.单引号和双引号的区别

双引号中可以包含字符串变量,能被解释器替换。单引号中的内容看成普通字符串,即使有变量也不会被解释器替换。

4.isset 和 empty 的区别

参考:‘https://www.wizardcode.cn/2018/02/02/45.html’

php中 零,空字符串,false,null ,不存在的变量 在empty中都返回true。

php中,null和不存在的变量在isset中返回false。

php数据中,键名存在,键值为null,可通过array_key_exists判断是否存在。

5.echo、print_r、print、var_dump 之间的区别

echo
可以一次输出多个值,多个值之间用逗号分隔。echo是语言结构(language construct),而并不是真正的函数,因此不能作为表达式的一部分使用。

print
函数print打印一个值,如果字符串成功显示则返回true,否则返回false。

print_r()
可以把字符串和数字简单地打印出来,而数组则以括起来的键和值得列表形式显示,并以Array开头。但print_r()输出布尔值和NULL的结果没有意义,因为都是打印”\n”。

var_dump()
判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型。此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。

PHP代码
$data=[1];
echo '-----echo ----'."\n";
echo false;
echo null;
echo '-----print ----'."\n";
print false;
print null;
echo '-----print_r ----'."\n";
print_r(false);
print_r(null);
print_r($data);
echo '-----var_dump ----'."\n";
var_dump(false);
var_dump(null);
var_dump($data);
输出:
-----echo ----
-----print ----
-----print_r ----
Array
(
 [0] => 1
)
-----var_dump ----
bool(false)
NULL
array(1) {
 [0]=>
 int(1)
}
小总结:echo 可以使用逗号分开一次打印多个值,print有布尔返回值,print_r既可以打印一个值,也可以打印数组,已键值对的形式展示,var_dump()调试专用,有值类型。
前三个打印null和false均为输出,无意义。
6.什么是 MVC?
  MVC分别对应Model、View 和 Controller。
  视图:最上面的一层,是直接面向最终用户的"视图层"(View)。它是提供给用户的操作界面,是程序的外壳。
  控制器:最底下的一层,是核心的"数据层"(Model),也就是程序需要操作的数据或信息。
  模型:中间的一层,就是"控制层"(Controller),它负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作,产生最终结果。
  

7.传值和传引用的区别?

传值:仅将对象的值传递给目标对象,就相当于copy;系统将为目标对象重新开辟一个完全相同的内存空间。

引用:将对象在内存中的地址传递给目标对象,相当于使目标对象和原始对象对应同一个内存存储空间。此时,如果对目标对象进行修改,内存中的数据也会改变。

PHP中的引用可以理解成变量的别名。由于PHP的变量名是存储在符号表(symbol table)中的,变量内容是存储在堆中,引用就是用符号表中的不同符号(symbol)名称来访问同一存储内容。

$a = 1;
$b = &$a; //$a与$b指向同一内容
$b = 2;
echo $b; //2
echo $a; //2

引用与指针很像,但是其并不是指针

$a = 0;
$b = &a;
echo $a; //0
unset($a);
echo $b; //0
由于$b只是$a的别名,所以即使$a被释放了,$b没有任何影响,指针与此相反。

PHP 使用写时复制(Copy On Write)缩写为COW

PHP中的COW可以简单描述为:如果通过赋值的方式赋值给变量时不会申请新内存来存放 新变量所保存的值,而是简单的通过一个计数器来共用内存,只有在其中的一个引用指向变量的 值发生      变化时才申请新空间来保存值内容以减少对内存的占用。 在很多场景下PHP都COW进行内存的优化。比如:变量的多次赋值、函数参数传递,并在函数体内修改实参等。

多个相同值的变量共用同一块内存的确节省了内存空间,但变量的值是会发生变化的,如果在上面的例子中, 指向同一内存的值发生了变化(或者可能发生变化),就需要将变化的值“分离”出   去,这个“分离”的操作, 就是“复制”。

在PHP中,Zend引擎为了区别同一个zval地址是否被多个变量共享,引入了ref_count和is_ref两个变量进行标识,多一个变量指针,就将ref_count加1, 反之减去1,减到0就销毁; 同理,多一个强制引用&,就将is_ref加1,反之减去1。也是因为如此,unset($a)只是断了变量a和内存中数据之间的联系,而没有销毁对象回收内存。

慎用引用&,引用操作符会导致PHP的COW策略优化,所以使用引用也需要对引用的行为有明确的认识才不至于误用, 避免带来一些比较难以理解的的Bug。如下:

$data[‘age’] = 100;
$a = &$data[‘age’];
$b = $data;
$b[‘age’] = 200;
echo $data[‘age’];

输出:200.

$a 变量的引用操作将$data[‘age’]污染成了引用,从而zend没有对$b[‘age’]的修改产生内存复制分离。