PHP基础

文章目录
  1. 1. 标识符
  2. 2. 八种数据类型
  3. 3. GET 和 POST 的区别
  4. 4. 双引号和单引号的区别
  5. 5. isset 和 empty 的区别
  6. 6. echo(),print(),print_r(),var_dump()的区别
  7. 7. 传值和传引用的区别
  8. 8. Cookie 和 Session 的区别和关系
  9. 9. 常用的超全局变量(8个)
  10. 10. 语句include和require的区别
  11. 11. PHP进程间通信的几种方式
  12. 12. 简述 S.O.L.I.D 设计原则
  13. 13. 列举一些 PHP 中的设计模式
  14. 14. REST
  15. 15. PHP7 和 PHP5 的区别,具体多了哪些新特性
  16. 16. PHP7废弃函数
  17. 17. 简述一下 PHP 垃圾回收机制(GC)
  18. 18. 如何解决 PHP 内存溢出问题
  19. 19. foo()和 @ foo()之间有什么区别
  20. 20. GD库是做什么用的
  21. 21. 魔术方法
  22. 22. 魔术常量
  23. 23. PHP缓存技术
  24. 24. strlen()与mb_strlen的作用与区别
  25. 25. PHP的”::”、”->”和”=>”的区别
  26. 26. 实现服务器共享session
  27. 27. PDO中一共提供了三种不同的错误处理模式
  28. 28. PHP过滤器
  29. 29. PHP静态化
  30. 30. 面向过程与面向对象的优缺点
  31. 31. 文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?
  32. 32. 什么是构造函数,什么是析构函数,作用是什么
  33. 33. OOP编程模式
  34. 34. Boolean 以下值会被认定为
  35. 35. PHP语言在内存中的分配
  36. 36. PHP 中static 静态变量和普通变量的区别

PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)

标识符

标识符是指变量的名称。

八种数据类型

PHP一共支持八种数据类型,包括4种标量类型,即boolean(布尔型),integer(整形),float/double(浮点型)和string(字符串类型);两种复合类型,即array(数组),和object(对象);两种特殊类型,resource(资源)与null(空)。

GET 和 POST 的区别

GET - 从指定的资源请求数据。
POST - 向指定的资源提交要被处理的数据
| | GET | POST |
| — | — | — |
| 后退按钮/刷新 | 无害 | 再次提交请求 |
| 书签 | 可被保存为书签 | 不可保存为书签 |
| 缓存 | 能被保存 | 不能保存 |
| 编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
| 历史 | 被完整保留在浏览器历史记录里 | 不会被保留 |
| 对数据长度的限制 | URL 的最大长度是 2048 个字符 | 无限制 |
| 对数据类型的限制 | 只接受ASCII字符 | 无限制 |
| 安全性 | 参数直接暴露在URL上 | 参数不会被保存在浏览器历史或 web 服务器日志中 |
|TCP数据包| 一个 | 两个 |

其他 HTTP 请求方法:

  • HEAD 与 GET 相同,但只返回 HTTP 报头,不返回文档主体。
  • PUT 上传指定的 URI 表示。
  • DELETE 删除指定资源。
  • OPTIONS 返回服务器支持的 HTTP 方法。
  • CONNECT 把请求连接转换到透明的 TCP/IP 通道。
双引号和单引号的区别
  • 双引号解释变量,单引号不解释变量
  • 双引号里插入单引号,其中单引号里如果有变量的话,变量解释
  • 双引号的变量名后面必须要有一个非数字、字母、下划线的特殊字符,或者用{}将变量括起来,否则会将变量名后面的部分当做一个整体,引起语法错误
  • 双引号解释转义字符,单引号不解释转义字符,但是解释’\和\
  • 能使单引号字符尽量使用单引号,单引号的效率比双引号要高(因为双引号要先遍历一遍,判断里面有没有变量,然后再进行操作,而单引号则不需要判断)
isset 和 empty 的区别

isset - 判断一个变量是否设置(存在)
empty - 判断一个变量是否为空

1
2
echo !isset($_GET['a']); //如果得不到变量a的值 
echo empty($_GET['a']); //如果变量a的值是空

unset()
unset()这个函数的作用是删除指定的变量且传回true,参数为要删除的变量。

echo(),print(),print_r(),var_dump()的区别

简单来说:

  • echo()是PHP语句,print和print_r是函数,语句没有返回值,函数可以有返回值(即便没有用)
  • print()只能打印出简单类型变量的值(如int,string)
  • print_r() var_dump()可以打印出复杂类型变量的值(如数组,对象)

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

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

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

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

传值和传引用的区别
  • 传值 - 是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值

    1
    2
    3
    4
    5
    6
    <?php  
    $param1=1; //定义变量1
    $param2=2; //定义变量2
    $param2 = $param1; //变量1赋值给变量2
    echo $param2; //显示为1
    ?>
  • 传引用 - 真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值

    1
    2
    3
    4
    5
    6
    7
    <?php  
    $param2=1; //定义变量2
    $param1 = &$param2; //将变量2的引用传给变量1
    echo $param2; //显示为1
    $param1 = 2; //把2赋值给变量1
    echo $param2; //显示为2
    ?>
  • Cookie 在客户端(浏览器),Session 在服务器端
  • Session 比 Cookie 安全性更高
  • 单个 Cookie 保存的数据不能超过 4K
  • Session 是基于 Cookie,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 Session ID)
常用的超全局变量(8个)

超全局变量 — 超全局变量是在全部作用域中始终可用的内置变量

  • $_GET - get传送方式
  • $_POST – post传送方式
  • $_REQUEST - 可以接收到get和post两种方式的值
  • $_GLOBALS - 所有的变量都放在里面
  • $_FILE - 上传文件使用
  • $_SERVER - 系统环境变量
  • $_SESSION
  • $_COOKIE
  • $_ENV - 通过环境方式传递给当前脚本的变量的数组
语句include和require的区别
  • require是无条件包含,也就是如果一个流程里加入require,无论条件成立与否都会先执行require,当文件不存在或者无法打开的时候,会提示错误,并且会终止程序执行
  • include有返回值,而require没有(可能因为如此require的速度比include快),如果被包含的文件不存在的化,那么会提示一个错误,但是程序会继续执行下去。这个函数一般放在程序的流程控制里边。只有程序在执行碰到才会引用。可以简化程序的执行流程。

包含文件不存在或者语法错误的时候require是致命的,而include不是。

require_once表示了只包含一次,避免了重复包含。

PHP进程间通信的几种方式
  • 消息队列
  • 信号量+共享内存
  • 信号
  • 管道
  • socket
简述 S.O.L.I.D 设计原则
- - -
SRP 单一职责原则 一个类有且只有一个更改的原因
OCP 开闭原则 能够不更改类而扩展类的行为
LSP 里氏替换原则 派生类可以替换基类使用
ISP 接口隔离原则 使用客户端特定的细粒度接口
DIP 依赖反转原则 依赖抽象而不是具体实现
列举一些 PHP 中的设计模式
  • 单例模式:保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个,同时这个类还必须提供一个访问该类的全局访问点。
  • 工厂模式:定义一个创建对象的接口,但是让子类去实例化具体类。工厂方法模式让类的实例化延迟到子类中。
  • 观察者模式:观察者模式有时也被称作发布/订阅模式,该模式用于为对象实现发布/订阅功能:一旦主体对象状态发生改变,与之关联的观察者对象会收到通知,并进行相应操作。
  • 适配器模式:适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
  • 依赖注入模式:依赖注入(Dependency Injection)是控制反转(Inversion of Control)的一种实现方式。要实现控制反转,通常的解决方案是将创建被调用者实例的工作交由 IoC 容器来完成,然后在调用者中注入被调用者(通过构造器/方法注入实现),这样我们就实现了调用者与被调用者的解耦,该过程被称为依赖注入。
  • 门面模式:门面模式(Facade)又称外观模式,用于为子系统中的一组接口提供一个一致的界面。
REST

REST服务,RESTful风格。

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。
REST请求方法有4种,包括GET、POST、PUT、DELETE分别对应获取资源,添加资源,更新资源及删除资源。
多数为描述API风格。
主要原则

  • 网络上的所有事物都被抽象为资源
  • 每个资源都有一个唯一的资源标识符
  • 同一个资源具有多种表现形式(xml,json等)
  • 对资源的各种操作不会改变资源标识符
  • 所有的操作都是无状态的
  • 符合REST原则的架构方式即可称为RESTful
PHP7 和 PHP5 的区别,具体多了哪些新特性
  • 性能提升了两倍
  • 增加了结合比较运算符 (<=>)
  • 增加了标量类型声明、返回类型声明
  • try…catch 增加多条件判断,更多 Error 错误可以进行异常处理
  • 增加了匿名类,现在支持通过new class 来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义

具体区别:

  • 标量类型声明 - 现在可以使用下列类型参数(无论用强制模式还是严格模式): 字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool)。

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    // Coercive mode
    function sumOfInts(int ...$ints)
    {
    return array_sum($ints);
    }

    var_dump(sumOfInts(2, '3', 4.1));
  • 返回值类型声明 - PHP 7 增加了对返回类型声明的支持。 类似于参数类型声明,返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。

    1
    2
    3
    4
    5
    6
    7
    8
    <?php

    function arraysSum(array ...$arrays): array
    {
    return array_map(function(array $array): int {
    return array_sum($array);
    }, $arrays);
    }
  • null合并运算符 - 如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    // Fetches the value of $_GET['user'] and returns 'nobody' if it does not exist.
    $username = $_GET['user'] ?? 'nobody';
    // This is equivalent to:
    $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

    // Coalesces can be chained: this will return the first defined value out of $_GET['user'], $_POST['user'], and 'nobody'.
    $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
    ?>
  • 太空船操作符(组合比较符)- 太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?php
    // 整数
    echo 1 <=> '1'; // 0
    echo 1 <=> 2; // -1
    echo 2 <=> 1; // 1

    // 浮点数
    echo '1.50' <=> 1.5; // 0
    echo 1.5 <=> 2.5; // -1
    echo 2.5 <=> 1.5; // 1

    // 字符串
    echo "a" <=> "a"; // 0
    echo "a" <=> "b"; // -1
    echo "b" <=> "a"; // 1
    ?>
  • 通过 define() 定义常量数组 - Array 类型的常量现在可以通过 define() 来定义。在 PHP5.6 中仅能通过 const 定义。

PHP7废弃函数

mysql相关函数全部废弃,用mysqli代替。
在 PHP4 中类中的函数可以与类名同名,这一特性在 PHP7 中被废弃。

简述一下 PHP 垃圾回收机制(GC)

PHP 5.3 版本之前都是采用引用计数的方式管理内存,PHP 所有的变量存在一个叫 zval 的变量容器中,当变量被引用的时候,引用计数会+1,变量引用计数变为0时,PHP 将在内存中销毁这个变量。
但是引用计数中的循环引用,引用计数不会消减为 0,就会导致内存泄露。

在 5.3 版本之后,做了这些优化:

  1. 并不是每次引用计数减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收;
  2. 可以解决循环引用问题;
  3. 可以总将内存泄露保持在一个阈值以下。
如何解决 PHP 内存溢出问题
  • 增大 PHP 脚本的内存分配
  • 变量引用之后及时销毁
  • 将数据分批处理
foo()和 @ foo()之间有什么区别
  • @foo()控制错误输出,foo()正常表达

PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。

@ 运算符只对表达式有效。

例如,可以把它放在变量,函数和include()调用,常量,等等之前。不能把它放在函数或类的定义之前,也不能用于条件结构例如if 和 foreach 等。

GD库是做什么用的

GD库,是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片。

魔术方法

PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用。 魔术方法包括:

  • __construct(),类的构造函数
  • __destruct(),类的析构函数,是对象被销毁时被自动调用的,作用是释放内存
  • __call(),在对象中调用一个不可访问方法时调用
  • __callStatic(),用静态方式中调用一个不可访问方法时调用
  • get(),当程序调用一个未定义或不可见的成员属性时,自动触发执行get()。它有一个参数,表示要调用的属性的名称
  • set(),当程序试图写入一个不存在或不可见的成员属性时,PHP就会自动执行set()。它包含两个参数,分别表示属性名称和属性值
  • __isset(),当对不可访问属性调用isset()或empty()时调用
  • __unset(),当对不可访问属性调用unset()时被调用。
  • __sleep(),执行serialize()时,先会调用这个函数
  • __wakeup(),执行unserialize()时,先会调用这个函数
  • __toString(),类被当成字符串时的回应方法(echo 类)
  • __invoke(),调用函数的方式调用一个对象时的回应方法
  • __set_state(),调用var_export()导出类时,此静态方法会被调用。
  • clone(),当程序clone一个对象的时候,能触发clone()方法,程序希望通过这个魔术方法实现:不仅仅单纯地克隆对象,还需要克隆出来的对象拥有原来对象的所有属性和方法
  • autoload(),当程序实例化某个类,而该类没有在当前文件中被引入。此时会触发执行autoload()。程序希望通过该方法,自动引入这个类文件
  • __debugInfo(),打印所需调试信息
魔术常量
  • __LINE__ - 返回文件中的当前行号。
  • __FILE__ - 返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,FILE 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。
  • __FUNCTION__ - 返回函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在PHP 4 中该值总是小写字母的。
  • __CLASS__ - 返回类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在PHP 4 中该值总是小写字母的。
  • __METHOD__ - 返回类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
PHP缓存技术
  1. 全页面静态化缓存,也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程
  2. 页面部分缓存,将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示
  3. 数据缓存,通过一个id进行请求的数据,将数据缓存到一个php文件中,id和文件是对应的,下次通过这个id进行请求时 直接读php文件
  4. 查询缓存,和数据缓存差不多,根据查询语句进行缓存;
  5. 内存式缓存,常用的缓存技术有:redis和memcache
  6. APC缓存,使用PHP的APC扩展
  7. apache缓存模块
strlen()与mb_strlen的作用与区别

在PHP中,strlen与mb_strlen是求字符串长度的函数。
PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得到的只是字符串所占的字节数。对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍(在 UTF-8编码下,一个汉字占3个字节)。

采用mb_strlen函数可以较好地解决这个问题。mb_strlen的用法和strlen类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串str长度,可以用mbstrlen(str,’UTF-8’)。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过 mb_internal_encoding()函数得到。

需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函 数的问题。

PHP的”::”、”->”和”=>”的区别
  1. “::” 运算法 - 该运算符是调用一个类中的静态成员(静态方法、静态属性)的方法。作用域解析操作符(Scope Resolution operator),用于调用类的静态成员变量或是类之间的调用。
  2. “->”运算符 - 操作符是操作一个类中的成员变量的方法,可以是非static成员变量。插入式解引用操作符(infix dereference operator),将对象的引用指向对象,例如对象->对象的方法。
  3. “=>”运算符 - 该预算付是数组的key和value映射时使用的运算符。

静态属性不能通过一个类已实例化的对象来访问,但静态方法可以。

实现服务器共享session

1. 基于NFS的Session共享
NFS是Net FileSystem的简称,最早由Sun公司为解决Unix网络主机间的目录共享而研发。
这个方案实现最为简单,无需做过多的二次开发,仅需将共享目录服务器mount到各频道服务器的本地session目录即可,缺点是NFS依托于复杂的安全机制和文件系统,因此并发效率不高,尤其对于session这类高并发读写的小文件,会由于共享目录服务器的io-wait过高,最终拖累前端WEB应用程序的执行效率。

2. 基于数据库的Session共享
首选当然是大名鼎鼎的Mysql数据库,并且建议使用内存表Heap,提高session操作的读写效率。这个方案的实用性比较强,相信大家普遍在使用,它的缺点在于session的并发读写能力取决于Mysql数据库的性能,同时需要自己实现session淘汰逻辑,以便定时从数据表中更新、删除 session记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不否认使用数据库存储Session还是有些杀鸡用牛刀的架势。

3. 基于Cookie的Session共享
这个方案我们可能比较陌生,但它在大型网站中还是比较普遍被使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式,统一种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现用户的Cookie化Session 在多服务间的共享访问。
这个方案的优点无需额外的服务器资源;缺点是由于受http协议头信心长度的限制,仅能够存储小部分的用户信息,同时Cookie化的 Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在http头中传递到服务器。

4. 基于Memcache的Session共享
Memcache由于是一款基于Libevent多路异步I/O技术的内存共享系统,简单的Key + Value数据存储模式使得代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势。另外值得一提的是Memcache的内存hash表所特有的Expires数据过期淘汰机制,正好和Session的过期机制不谋而合,降低了过期Session数据删除的代码复杂度,对比“基于数据库的存储方案”,仅这块逻辑就给数据表产生巨大的查询压力。

PDO中一共提供了三种不同的错误处理模式
  1. PDO::ERRMODE_SILENT:不报错误
  2. PDO::ERRMODE_WARNING:以警告的方式报错
  3. PDO::ERRMODE_EXCEPTION:以异常的方式报错
PHP过滤器

validating过滤器
1.用于验证用户输入。
2.严格的格式规则。(比如 URL 或 E-Mail 验证)
3.如果成功则返回预期的类型,失败则返回 false。

sanitizing过滤器
1.用于允许或禁止字符串中指定的字符。
2.无数据格式规则。
3.始终返回字符串。

PHP静态化

PHP静态化分为:纯静态化 和 伪静态化;
纯静态化又分为:局部静态化 和 完全静态化
纯静态化:是把PHP生成的动态页面保存成静态的html文件,用户访问该静态页面,而不是用户每一次访问都重新生成一张相同的网页,优点就是减小服务器开销,

  • 局部静态化:是生成的静态文件中,有局部的数据还是通过ajax技术动态获取的;
  • 完全静态化:即不存在动态获取数据的情况,所以内容都来自静态的html页面

伪静态化:其实还是动态访问,其实质是动态生成数据,你访问的网址类似于”http://yourhost,com/index/post/12",是一个静态地址,该地址多见于博客地址,但伪静态化中,你访问的网址实际上经过服务器解析,还是会解析成类似于"http://yourhost,com/?c=index&a=post&id=12"的地址,所以称之为伪静态化
伪静态的优点:美观;便于搜索引擎收录

面向过程与面向对象的优缺点

面向过程
  优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
  缺点:没有面向对象易维护、易复用、易扩展

面向对象
  优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
  缺点:性能比面向过程低

文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?

1). 首现要在php.ini中开启文件上传;
2). 在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;
3). 上传表单一定要记住在form标签中写上enctype=”multipart/form-data”;
4). 提交方式 method 必须是 post;
5). 设定 type=”file” 的表单控件,并且必须具有name属性值;
6). 为了上传成功,必须保证上传文件的大小是否超标、文件类型是否符合要求,上传后存放的路径是否存在;
7). 表单提交到接收页面,接收页面使用$_FILES来接收上传的文件。
$_FILES是个多维数组。第一维下标是上传控件的name,二维下标分别为name/type/tmp_name/size/error。分别代表
文件名、文件类型、上传到临时目录下的临时文件名、文件大小、是否有错误。
如果是批量上传,那么二维下标就是数组,而并非是字符串。
8). 文件上传后是被放置在服务器端临时路径下,需要使用move_uploaded_file ()函数,才可以将上传后的文件保存到指定目录。
9). 为了避免上传文件重名,可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名。

什么是构造函数,什么是析构函数,作用是什么

构造函数(方法)是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。作用是执行一些初始化的任务。Php中使用__construct()声明构造方法,并且只能声明一个。
析构函数(方法)作用和构造方法正好相反,是对象被销毁之前最后一个被对象自动调用的方法。是PHP5中新添加的内容作用是用于实现在销毁一个对象之前执行一些特定的操作,诸如关闭文件和释放内存等。

OOP编程模式

OOP 的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。

四大基本特性

  • 抽象:提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对类进行实例化得到对象。
  • 封装:封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等)
  • 继承:对现有类的一种复用机制。一个类如果继承现有的类,则这个类将拥有被继承类的所有非私有特性(属性和操作)。这里指的继承包含:类的继承和接口的实现。
  • 多态:多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多态特性。多态可以分成编译时多态和运行时多态。

抽象、封装、继承和多态是面向对象的基础。在面向对象四大基础特性之上,我们在做面向对象编程设计时还需要遵循有一些基本的设计原则。

七大设计原则

  • SOLID原则(单一职责原则、开放关闭原则、里氏替换原则、接口隔离原则和依赖倒置原则)
  • 迪米特法则
  • 组合优于继承原则(合成复用原则)
Boolean 以下值会被认定为
  • FALSE
  • FALSE本身
  • 整型 0
  • 浮点型 0.0
  • 空字符串,字符串”0″
  • 不包括任何元素的数组
  • 特殊类型NULL(包括还未赋值的变量)
  • 从空标记生成的SimpleXML对象
  • 其他资源都会被认为true
PHP语言在内存中的分配

初始化静态常量段:通常是指用来存放程序中已初始化且不为0的全局变量如:静态变量和常量。

代码段:通常是指用来存放程序执行代码的一块内存区域,比如函数和方法。

栈空间段:是存储占用相同空间长度并且占用空间小的数据类型的地方,比如说整型1,10,100,1000,10000,100000 等等,在内存里面占用空间是等长的,都是64位4个字节。存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。所以在栈空间的数据都是可以通过代码手动进行释放。

栈内存段:数据长度不定长,而且占有空间很大的数据类型的数据。在堆内存是里是不可以直接存取的内存,堆内存存储的是数组和对象(其实数组就是对象)。凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,最后通过垃圾回收机制去实现垃圾回收。对于我们的对象来数就是一种大的数据类型而且是占用空间不定长的类型,所以说对象是放在堆里面的,但对象名称是放在栈里面的,这样通过对象名称就可以使用对象。

堆与栈的区别:

  • 栈内存存储的是局部变量而堆内存存储的是实体;
  • 栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
  • 栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的
PHP 中static 静态变量和普通变量的区别

在变量的前面加上static 就构成了静态变量(static 变量)。

static变量和普通变量的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。

static变量和普通变量的区别

static全局变量与普通全局变量区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。
在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。

  1. 内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)
  2. 初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)
  3. 作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。