PS:欢迎指正内容不严谨或有误的地方!
网络相关
1.HTTP/HTTPS的区别
- 安全性不同:HTTPS用的是 SSL(安全套接字)/TSL加密的,而HTTP是使用明文传输的;
- HTTPS协议需要到CA申请证书;
- HTTP和HTTPS使用的是完全不同的连接方式,同时使用的端口也不同,HTTP是80端口,HTTPS是443端口。
- 网络模型中HTTP工作于应用层,HTTPS工作于传输层。
HTTPS工作原理:
- 客户端请求HTTPS网站,服务器受到请求,选择浏览器支持的加密和hash算法,同时返回数字证书(颁发机构/网址/公钥/证书有效期等信息)给浏览器;
- 浏览器对数字证书进行校验,有问题则提示警告;否则,生成一个随机数 X ,同时使用证书中的公钥进行加密,并发送给服务器;
- 服务器受到后,使用私钥解密,得到随机数 X ,然后使用该随机数对网页内容进行加密,返回给浏览器;
- 浏览器再次使用 X 和约定的加密算法对数据进行解密,得到最终的网页内容。
2.优化页面加载速度
- 服务器资源仅在使用时打开,其他时间关闭;
2,数据库添加合适的索引,优化查询速度; - 对于变动频率低的页面生成静态页面,缓存至服务器(Web Server);
- 图片等大文件单独放在一个服务器(OSS);
- 经常查询的变动频率低的数据,放在缓存服务器中(Redis);
3.GET/POST的区别
PS:本质上俩种请求方式并没有什么不同(本质上都是HTTP请求),仅仅是因为 RFC 规定为了让请求更加语义化;
- GET 使用
URL 或者 Cookie 传参,而 POST 将数据放在 Body 中传递(实际上GET也可以在body中传递参数); - GET 使用
URL 传递参数数据时,会有长度限制,而 POST 使用 Body 传递的数据可以非常大(实际上HTTP并没有对其进行长度限制,长度限制不过是服务器或者浏览器为了性能和安全防止恶意构造URL的攻击); - POST 比 GET 安全,因为数据在地址栏不可见(实际上作为HTTP请求,俩者都是明文传输,不存在安全一说,若想安全传输数据,请使用HTTPS);
4.session和cookie的区别
session和cookie都是跨页面不跨用户。 区别:
- session 可以存储任意类型的数据,而 cookie 只能存储字符串;
- cookie 由服务器生成,存储在客户端;session 同样由服务器生成,且存储在服务器;
- session 会占用服务器资源,而 cookie 不会;
- 单个 cookie 保存的数据不能超过 4k,浏览器对一个站点的cookie数一般有限制(20);
- 由于 cookie 并不安全,所以一般敏感信息放在 session 上,cookie 上放一些非重要信息;
PS:当用户通过浏览器发送请求至服务器时,服务器会自动生成一个 session(在 session 销毁前,session 中是可以以 key-value 的形式暂时存放一些用户信息的) 和 sessionID 用来标识这个唯一的 session,sessionID 会在响应浏览器时带回; 当浏览器接收到 sessionID 后会将这个唯一的 sessionID 存储起来(一般是通过 cookie 保存),待到下次发起请求时,浏览器会将该 sessionID 放在请求中一并发送给服务器, 从而达到保持用户状态的作用,服务器从请求中提取到 sessionID 后,就能找到对应用户的 session 从而获取相关用户信息;
5.HTTP常见的返回状态码
1XX:信息类-接收的请求正在处理
100 :继续请求;101 :切换协议; 2XX:成功-请求正常处理完毕200 OK :请求已被正常处理;204 No Content :请求已被正常处理,但响应无实体;206 Partial Content :客户端进行了范围请求,且服务器已成功响应; 3XX:重定向-需要进行附加操作以完成请求301 Moved Permanently :永久性重定向;302 FOUND :临时重定向;304 Not Modified :客户端发送了附加条件的请求,且服务器允许访问该资源,但不满足附加条件; 4XX:客户端错误-服务器无法处理请求400 Bad Request :请求报文中存在语法错误;401 Unauthrized :请求需要通过HTTP认证信息(网关未通过);403 Forbidden :该请求被服务器拒绝;404 Not Found :该请求在服务器上无法找到; 5XX:服务器错误-服务器处理请求出错500 Internal Serevr Error :服务器在执行请求时发送了错误;503 Service Unaviailable :服务器超负载或正在进行停机维护;
6.如何防止SQL注入
所谓的SQL注入攻击,即一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。 用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据。
解决方案:
- 对用户的输入进行校验,使用正则表达式过滤传入的参数;
- 使用参数化的语句,不要拼接SQL,也可以使用安全的存储过程;
- 不要使用管理员权限的数据库连接,为每个应用使用权限优先的数据库连接;
- 检查数据存储类型;
- 重要的信息进行加密;
7.如何防止XSS
跨站脚本主要被攻击者利用来读取网站用户的cookies或者其他个人数据,一旦攻击者得到这些数据,那么他就可以伪装成此用户来登录网站,获得此用户的权限。
解决方案:
- 将重要的 cookie 标记为
http only 不允许 JavaScript 获取该 cookie ; - 只允许用户输入我们期望的数据,其他数据过滤掉;
- 过滤或移除特殊的HTML标签
<script>/<iframe> 等; - 过滤 JavaScript 事件
onclick/onfocus ;
8.如何防止CSRF(跨站点请求伪造)
攻击者伪造目标用户的HTTP请求,然后此请求发送到有CSRF漏洞的网站,网站执行此请求后,引发跨站请求伪造攻击。 攻击者利用隐蔽的HTTP连接,让目标用户在不注意的情况下单击这个链接,由于是用户自己点击的,而他又是合法用户拥有合法权限, 所以目标用户能够在网站内执行特定的HTTP链接,从而达到攻击者的目的。
解决方案:
- 重要数据交互采用POST请求进行接收,虽然POST也可能不安全;
- 使用验证码,设计数据交互的情况下使用验证码验证(辅助手段);
- 验证
HTTP Referer 字段,该字段记录了此次HTTP请求的来源地址,最常见的是图片防盗 - 为每个表单添加令牌
token 验证。
9.大流量网站,如何解决访问量问题
- 确认服务器硬件是否足够支持当前的流量;
- 优化数据库访问;
- 禁止外部盗链;
- 控制大文件的下载;
- 使用不同主机分流主要流量(负载均衡);
- 使用流量分析统计软件监控流量。
10.浏览器请求网址的全过程
- 首先通过DNS服务器将域名解析成一个IP地址,通过IP和子网掩码判断是否属于同一个子网;
- 构造应用层请求HTTP报文,传输层添加TCP/UDP头部,网络层添加IP头部,数据链路层添加以太网协议头部;
- 数据经过路由器、交换机转发到目标服务器,目标服务器解析数据,最终拿到HTTP报文,按照对应的程序逻辑进行响应。
域名解析 –> 发起TCP的3次握手 –> 建立TCP连接后发起http请求 –> 服务器响应http请求,浏览器得到html代码 –> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) –> 浏览器对页面进行渲染呈现给用户
11.TCP和UDP的区别
- 是否基于连接:TCP是面向连接的协议,而UDP是无连接(发送数据无需建立连接)的协议;
- 可靠性与有序性:TCP提供交付保证,且保证消息的有序性;而UDP不提供任何有序性和可靠性;TCP是全双工的可靠信道,而UDP是不可靠信道;
- 实时性:UDP具有较好的实时性,工作效率比TCP高,适用于高速传输和实时性较高的通信或广播通信;
- 协议首部大小:TCP首部开销20个字节,UDP只有8个字节;
- 运行速度:UDP无需建立连接,无需保证消息的可靠交付和有序性,因此速度更快;
- 拥塞机制:UDP没有拥塞机制,因此网络出现拥塞不会导致源主机的发送效率降低;
- TCP面向字节流,UDP面向报文;
- TCP资源占用比UDP占用多;
- 每条TCP连接只能是点到点;而UDP支持一对一,一对多,多对一和多对多的交互通信。
所以UDP和TCP优缺点很明显:
- UDP:简单、传输快,但却不可靠、不稳定;适用于对可靠性要求不高的实时传输场景;
- TCP:可靠、稳定,但效率低。慢、占用资源多,易被攻击;适用于对网络质量有要求的传输场景。
12.TCP三次握手和四次挥手
三次握手
建立连接前 server 端需要监听端口,所以初始状态是 LISTEN
- client端请求建立连接,发送一个 SYN 同步包,发送后状态变更为 SYS_SENT
- server端收到SYN后,统一建立连接,返回一个ACK响应,同时也会个client端发送一个SYN包,发送完成后状态变更为 SYN_RCVD
- client端收到server的ACK之后,状态变更为 ESTABLISHED ,返回ACK给server端。server收到之后状态也变为ESTABLISHED,连接建立完成;
四次握手
- client端向server端发送 FIN 包,进入 FIN_WAIT_1 状态,代表client端已经没有数据要发送了(请求结束);
- server端收到之后,返回一个ACK,进入CLOSE_WAIT等待关闭状态,因为server端可能还有没有发送完成的数据;
- 等到server端数据都发送完毕之后,server端向client发送FIN包,进入LAST_ACK状态;
- client收到ACK后进入FIN_WAIT_2的状态,继续等待server端的数据,当收到server的FIN包后,client进入TIME_WAIT状态,
然后向server回复ACK,SERVER收到ACK后直接进入CLOSED状态,连接关闭。而client要等到2MSL(最大报文生存期,windows 上1MSL是2min)的时间, 才会进入CLOSED状态
为什么要等待2MSL的时间才关闭
- 为了保证连接的可靠关闭。如果server没有收到最后一个ACK,那么就会重发FIN;
- 为了避免端口重用带来的数据混淆。如果client直接进入CLOSED状态,又使用相同的端口号向server建立一个连接,上一次连接的部分数据在网络中延迟到达server,数据就可能会发送混淆。
为什么是3次?2次,4次不行吗?
- 因为TCP是双工传输模式,不区分客户端和传输端,连接的建立是双向的过程。
- 如果只有俩次,无法做到双向连接的建立,从建立连接 server 回复的 SYN 和 ACK 合并成一次(server端受到SYN后可以同时发送ACK和SYN)
可以看出来,无需四次握手。 - 挥手为什么需要四次?因为挥手的 ACK 和 FIN 不能同时发送,因为数据发送的截止时间不同。
PHP基础
1.echo/print()/print_r()/var_dump()/printf()/sprintf()的区别
- echo: 语言结构,非函数,接收参数列表(可输出多个变量值),只能打印简单类型(int、string),没有返回值,不需要圆括号;
- print: 语言结构,非函数,仅接收一个参数(只能输出一个变量值),有返回值1,可以省略圆括号;
- print_r: 函数,可以打印复合类型,对于
array 和 object 会格式化打印,print_r($string, true) :不输出直接返回处理后的值; - var_dump: 函数,输出变量的内容、类型或字符串的内容、类型、长度,无返回值;
- printf: 函数,将文字格式化以后输出;
- sprintf: 函数,不打印,而是返回格式化后的字符串。
补充:
- 语言结构: php语言关键字、语言语法的一部分,不可以被用户定义或者添加到语言库中、它可以有也可以没有变量和返回值。
- 语言结构执行快的原因: 函数要先被解析成php解析器(Zend引擎)分解成语言结构、所以,函数比语言结构多了一层解析器、速度就想对慢了。
- PHP中有哪些语言结构: echo、print、die、isset、unset、include、require、array、list、empty
- 如何分辨语言结构和函数:
function_exists() 、php --rf - 语言结构和函数的区别: ①语言结构比函数执行快(见上);②语言结构出错不可再处理;③语言结构不可在
php.ini 中禁用,函数则可以通过 php.ini->disable_functions=... 参数禁用;④语言结构不可用作回调函数,函数可以。
2.PHP魔术方法
__construct() :具有构造函数的类会在每次创建新对象的时候调用这个方法。__destruct() :析构函数会在某个对象的所有引用都被都被删除或者当对象被显示销毁时执行。__call() :在对象中调用一个不可访问的方法时会被执行;__callStatic() :在静态上下文中调用一个不可访问方法时,该方法会被执行。__get() :读取不可方法的属性的值时,该方法会执行。__set() :给不可访问的属性赋值时,该方法会执行。__isset() :对不可访问的属性调用 isset()/empty()时,该方法会执行。__unset() :对不可访问的属性调用 unset() 时,该方法会执行。__sleep() : serialize() 函数会在执行前检查类中是否有 __sleep() 方法,有则会先执行该方法。 (此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。)__wakeup() : unserialize() 函数则会在执行前检查类中是否有 __wakeup() 方法,有则会先执行该方法。 (经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。 )__toString() : 当一个类被当成字符串处理时会执行该方法。__invoke() : 当尝试以函数的方法调用一个对象时会触发该方法。__set_state() : 使用 var_export() 导出一个类时,该静态方法会被调用。__clone() : 当克隆一个对象时,克隆完成后,该方法会被调用; (可用于修改对象的属性值)__debugInfo() : 打印该对象时执行该方法。
魔术常量:
__LINE__ :文件中的当前行号;__FILE__ :文件的完整路径和文件名;__FUNCTION__ :函数名称;__CLASS__ :类的名称;__METHOD__ :类的方法名;
3.PHP显示客户端和服务器IP
echo $_SERVER['REMOTE_ADDR'];
echo $_SERVER['SERVER_ADDR'];
4.require和include的区别
官方文档: require 和 include 几乎完全一样,除了处理失败的方式不同之外。 require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告E_WARNING ,脚本会继续运行。
include_once 语句在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次。
5.error_reporting()函数的作用
error_reporting(2047);
error_reporting('E_ALL');
6.foo()和@foo()的区别
@ :错误控制运算符,当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。
7.mysql_fetch_row()和mysql_fetch_array()的区别
mysql_fetch_row() : 从和指定的结果标识关联的结果集中取得一行数据并作为数组返回。每个结果的列储存在一个数组的单元中,偏移量从 0 开始。mysql_fetch_array() :结果集中取得一行作为关联数组,或数字数组,或二者兼有;
区别:
mysql_fetch_array() 是 mysql_fetch_row() 的扩展版本。除了将数据以数字索引方式储存在数组中之外,还可以将数据作为关联索引储存,用字段名作为键名。
8.面向对象编程
- 封装: 保证软件程序在具有优良的模块性的基础上,封装的目的就是要实现软件程序的高内聚,低耦合,防止程序相互依赖而带来的变动影响;
- 继承: 继承是子类自动共享父类数据和方法的机制,是类之间的一种关系,提高了软件的可重用性和可扩展性;
- 多态: 指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是根据程序运行期间确定的,即该引用变量到底会指向哪个类的实例对象不是一开始就决定好的,而是程序运行期间才决定的。
- 抽象: 指编写程序时找出一些事务的相似和共性之处,然后将这些事务归为一个类,该类仅考虑相似和共性之处,忽略其他无关方面。
9.PHP加密函数
- crypt():
- md5():
- sha1():
- Mcrypt() | Mash: 加密扩展库。
10.sort()/asort()/ksort()的区别
sort() :对数组进行排序,不保持索引关系;asort() :对数组进行排序并保持索引关系;ksort() :对数组按照键名排序
11.PHP中如何修改SESSION的生存时间
12.PHP中HEREDOC使用规范
结束时所引用的标识符必须在该行的第一列,而且,标识符的命名也要像其它标签一样遵守 PHP 的规则:只能包含字母、数字和下划线,并且必须以字母和下划线作为开头。
13.isset()和empty()的区别
14.varchar和char的区别
15.常用字符串函数
- trim(): 去除字符串首尾处的空白字符(或者其他字符),此外还有
ltrim() 和 rtrim() ; - strlen(): 获取字符串长度;
- mb_strlen(): 获取字符串长度(可指定字符编码,对中文字符串计算长度);
- substr(): 返回字符串的一部分;
- str_replace(): 子字符串替换;
- str_repeat(): 重复一个字符串;
- is_string(): 检测变量是否是字符串;
- str_shuffle(): 随机打乱一个字符串;
- sprintf(): 返回根据格式化字符串生成的字符串(通常用于获取分表后的数据表名);
- strstr(): 查找字符串的首次出现;
- explode(): 使用一个字符串分割另一个字符串;
- implode(): 将一个一维数组转换为字符串;
- strrev(): 反转字符串;
- strpos(): 查找字符串首次出现的位置;
- strtolower()|strtoupper(): 将字符串转换为小写|大写;
16.常用数组函数
- in_array(): 判断元素是否在数组中;
- count(): 返回数组长度;
- array_merge(): 将多个数组合并成一个数组;
- array_diff(): 计算数组差集;
- array_intersect(): 计算数组交集;
- array_keys(): 获取数组的key列表;
- array_values(): 返回数组中的所有值;
- array_column(): 返回数组中指定的一列;
- array_unique(): 移除数组中重复的值;
- array_push(): 将一个或多个单元压入数组的末尾(入栈);
- array_pop(): 弹出数组最后一个单元(出栈)
- array_shift(): 将数组开头的单元移出数组;
- array_unshift(): 在数组开头插入一个或多个单元;
- array_walk(): 使用用户自定义函数对数组中的每个元素做回调处理;
17.常用文件|目录处理函数
- fopen(): 打开文件或URL;
- fget(): 读取文件;
- fwrite(): 写入文件;
- fclose(): 关闭文件句柄;
- rename(): 移动/重命名文件;
- copy(): 复制文件;
- unlink(): 删除文件;
- touch|vim: 创建文件;
- fileatime(): 获取文件上次访问时间;
- filemtime(): 获取文件上次修改时间;
- filesize(): 获取文件大小;
- filetype(): 获取文件类型;
- state(): 获取文件详细信息;
- is_dir(): 判断是否是目录;
- file_get_contents(): 将整个文件读入一个字符串;
- file_put_contents(): 将一个字符串写入文件;
- opendir(): 打开目录;
- readdir(): 读取目录;
- rmdir(): 删除目录;
- closedir(): 关闭目录句柄;
- mkdir(): 创建目录;
- dirname(): 返回路径中的目录部分;
- scandir(): 列出指定路径中的文件和目录;
18.时间处理函数
- date(): 格式化一个本地时间/日期;
- getdate(): 取得日期/时间信息;
- date_default_timezone_set(): 设定默认时区;
- date_default_timezone_get(): 返回默认时区;
- mktime($hour, $minute, $second, $month, $day,
y
e
a
r
[
,
year[,
year[,is_dst = -1]): 返回一个日期的Unix时间戳;
- strrotime(): 将任何字符串的日期时间描述解析为 Unix 时间戳;
- strftime(): 根据区域设置格式化本地时间;
19.PHP数据类型
四种标量类型:
Boolean 布尔型;Interger 整型;Float 浮点型;string 字符串; 三种复合类型:array 数组类型;object 对象;callable 可调用; 俩种特殊类型:resource 资源;NULL 无类型;
20.等同于FALSE的值有哪些
- 布尔值:
FALSE 本省; - 整型:
0 ; - 浮点型:
0.0 ; - 字符串:空字符串
'' 以及字符串 '0' ; - 不包含任何元素的数组;
- 特殊类型
NULL (包括尚未赋值的变量); - 从空标记生成的 SimpleXML 对象
21.什么是MVC
MVC由 Model 、View 、Controller 组成
Model :模型层,为数据信息存取层;View :视图层,负责将应用的数据以特定的方式展现在界面上;Controller :控制器层,负责从视图读取数据,控制用户输入,并向模型层发送数据,最后将模型层返回的数据处理为正确的格式返回给视图层;
22.PHP中获取图像尺寸的方法
getimagesize($fileName[, $imageInfo]) :获取图片尺寸;imagesx($image) :获取图像宽度;imagesy($image) :获取图像高度;
23.PHP如何定义常量
define($name, $value[,$case_insensitive = false]) : 定义一个常量;const CONST_NAME = CONST_VALUE :定义一个常量
24.UTF-8转换为GBK的函数
iconv('GBK','UTF-8','string');
mb_convert_encoding('string','GBK','UTF-8');
25.PHP中分隔字符串成数组和链接数组成字符串的函数
explode($delimeter, $string[,$limit])
split($pattern, $string[,$limit])
implode($glue, $array)
join($glue, $array)
26.设计模式
- 单例模式: 保证每个类仅有一个实例,并提供一个访问它的全局访问点(如框架中的数据库连接);
- 简单工厂模式: 具有创建对象的某些方法,可以使用工厂类创建对象,而不直接使用
new 关键字; - 策略模式: 针对一组算法,将每种算法封装到具有共同接口的独立的类中(例如根据不同的用户展示不同的页面和操作);
- 注册模式: 提供了在程序中有条理的存放并管理一组全局对象
object ; - 适配器模式: 将不同的接口适配成统一的 API 接口(例如数据库操作mysql/mysqli/pdo可利用适配器模式统一接口);
- 观察者模式: 一个对象通过添加一个方法使本身变得可观察。当观察的对象更改时,它会将消息发送到已注册的观察者(消息推送);
- 装饰器模式: 不修改原类代码和继承的情况下动态扩展类的功能(例如大多数框架 controller 提供的
before 和 after 方法); - 迭代器模式: 提供一个方法顺序访问一个聚合对象中的各个元素,在PHP中将继承
iterator 类; - 原型模式: 实现一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。
27.PHP中非静态方法静态调用以及反之
- 非静态方法静态调用: 可以调用,会产生一个
strict 错误,但会继续执行代码; - 静态方法非静态调用: 不可调用,程序出错中断执行。
28.如何记录PHP程序错误至系统日志
①开启 log_errors ,默认记录错误至服务器的日志文件; ②指定错误日志记录的文件
display_errors=off;
log_errors=on;
error_log=/var/log/php_error.log;
error_log=syslog;
29.private、protected、public修饰符的访问权限
- private: 私有成员,在类的内部才可以访问;
- protected: 保护成员,该类的内部和继承类中可以访问;
- public: 公共成员,完全公开,没有访问限制;
30.堆和栈的区别
- 堆: 程序运行期间动态分配的内存空间,程序员可以根据程序运行的情况确定要分配的堆内存的大小;
- 栈: 在编译期间就分配好的内存空间,程序员在代码中必须就栈的大小有明确的定义;
31.抽象类和接口类的概念以及区别
抽象类时一种特殊的类,接口是一种特殊的抽象类。
- 定义抽象的类不能被实例化。
- 任何一个类,若它里面有至少一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
- 被定义为抽象的方法只是声明了其调用方法(参数),不能定义其具体的功能实现。
- 继承一个抽象类时,子类必须定义父类中的所有抽象方法;且这些方法的访问控制必须和父类中一样或更为宽松。
- 此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。(子类中可增加父类中没有的可选参数)
对象接口
- 使用接口可以指定某个类中必须实现哪些方法,但不需要定义这些方法的具体内容。
- 接口通过 interface 关键字来定义,就像定义一个标准类一样,但其中定义的所有方法都是空的。
- 接口中定义的所有方法都必须是公有的,这是接口的特性。
- 要实现一个接口 使用 implement 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。
- 一个类中可以实现多个接口,用逗号来分隔多个接口的名称。
- 接口中可以定义常量,接口常量的使用和类常量完全相同,但不能被子类或子接口所覆盖。
区别:
- 接口的继承可以使用 implements 和 extends, 抽象类则使用 extends。
- 接口中不可用声明变量,但可以声明类常量,抽象类中可以声明各种变量。
- 接口没有构造函数,抽象类可以有;
- 接口这种的方法必须为 public ,抽象类没有限制。
- 一个类可以继承多个接口,但只能继承一个抽象类。
32.如何重载父类的方法
重载:
- 即覆盖父类的方法,也就是使用子类中的方法替换从父类中继承的的方法(方法重写)。
- 覆盖父类方法的关键是在子类中创建于父类中相同的方法,包括方法的名称、参数和返回值类型(PHP仅要求名称相同)。
33.$this/self/parent
PS::: 被称为作用域操作符。
$this 当前对象,在当前类中使用,使用 $this->functionName() 或 $this->attribute 调用属性和方法;self 当前类,在当前类中使用,使用 slef::functioName() 或 self::CONST_NAME 调用当前类的静态方法和常量;parent 当前类的父类,在类中使用,使用 parent::functionNanme() 或 self::CONST_NAME 调用父类的静态方法或常量;
*34.__autoload()|spl_autoload_register()方法的工作原理
__autoload():
- 使用该魔术方法的基本条件是类文件的文件名要和类名称保持一致;
- 当程序执行到实例化某个类时,若在实例化前没有引入这个类,那么就会触发
__autoload() 函数; - 该函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后,将会执行
include 或 require 来载入该类,然后程序继续执行,若该路径下不存在该文件就会提示错误。 - 使用自动加载函数可以避免写很多个
include 或 require 函数;
PHP代码题
1.遍历文件夹下所有文件和子文件
function fileIterate($dir) {
$files = [];
if (is_dir($dir)) {
if ($handle = opendir($dir)) {
while(($file = readdir($handle)) !== false) {
if ($file != "." && $file != "..") {
if (is_dir($dir.'/'.$file)) {
$files[$file] = fileIterate($dir.'/'.$file);
} else {
$files[] = $dir.'/'.$file;
}
}
}
}
closedir($handle);
return $files;
}
return false;
}
$result = fileIterate(__DIR__);
print_r($result);
2.实现字符串翻转
function strReverse($str) {
$revStr = '';
if ($str == $revStr) return $revStr = '';;
for ($i = (strlen($str) - 1); $i >= 0; $i--) {
$revStr .= $str[$i];
}
return $revStr;
}
3.获取网页内容
$url = 'www.baidu.com';
$file = fopen($url, 'rb')
$content = stream_get_contents($file);
fclose($file);
echo $content;
echo file_get_contents($url);
4.PHP操作数据库的流程
mysqli
$mysqli = new mysqli('localhost', 'root', 'root','db_users');
if($mysqli->connect_errno) die('连接错误:'.$mysqli->connect_error);
$mysqli->set_charset('utf8');
$sql = 'INSERT `user` SET `username`=?,`password`=?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ss', $name, $pwd);
$name = 'php';
$pwd = md5('php.cn');
$stmt->execute() or die($stmt->error);
$aff_rows = $stmt->affected_rows;
$ins_id = $stmt->insert_id;
echo '新增了'.$aff_rows.'条数据,新增的主键ID='.$ins_id.'<br>';
$sql = 'UPDATE `user` SET `username`=?,`password`=? WHERE `id`=?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ssi', $name, $pwd, $id);
$name = 'mysqli';
$pwd = md5('mysqli');
$id = $ins_id;
$stmt->execute() or die($stmt->error);
$aff_rows = $stmt->affected_rows;
echo '更新了'.$aff_rows.'条数据'.'<br>';
$sql = 'DELETE FROM `user` WHERE `id`=?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $id);
$id = $ins_id;
$stmt->execute() or die($stmt->error);
$aff_rows = $stmt->affected_rows;
echo '删除了'.$aff_rows.'条数据'.'<br>';
$sql = 'SELECT `username` FROM `user` WHERE `id`=?';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $id);
$id = 1;
$stmt->execute() or die($stmt->error);
$result = $stmt->get_result();
if($result->num_rows > 0) vprintf('查找结果:%s',$result->fetch_assoc());
PDO
$dsn = 'mysql:host=localhost;dbname=db_users;charset=utf8';
$pdo = new PDO($dsn, 'root', 'root');
$sql = 'INSERT `user` SET `username`=?,`password`=?';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $pwd);
$name = 'php';
$pwd = md5('php.cn');
$stmt->execute();
$aff_rows = $stmt->rowCount();
$ins_id = $pdo->lastInsertId();
echo '新增了'.$aff_rows.'条数据,新增的主键ID='.$ins_id.'<br>';
$name = 'php';
$pwd = md5('php.cn');
$stmt->bindValue(1, $name);
$stmt->bindValue(2, $pwd);
$stmt->execute();
$aff_rows = $stmt->rowCount();
$ins_id = $pdo->lastInsertId();
echo '新增了'.$aff_rows.'条数据,新增的主键ID='.$ins_id.'<br>';
$stmt->execute(['php',md5('php')]);
$aff_rows = $stmt->rowCount();
$ins_id = $pdo->lastInsertId();
echo '新增了'.$aff_rows.'条数据,新增的主键ID='.$ins_id.'<br>';
$sql = 'UPDATE `user` SET `username`=?,`password`=? WHERE `id`=?';
$stmt = $pdo->prepare($sql);
$stmt->execute(['mysqli', md5('mysqli'), $ins_id]);
$aff_rows = $stmt->rowCount();
echo '更新了'.$aff_rows.'条数据'.'<br>';
$sql = 'DELETE FROM `user` WHERE `id`=?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$ins_id]);
$aff_rows = $stmt->rowCount();
echo '删除了'.$aff_rows.'条数据'.'<br>';
$sql = 'SELECT `username` FROM `user` WHERE `id`=?';
$stmt = $pdo->prepare($sql);
$stmt->execute([1]);
$result = $stmt->fetch();
vprintf('查找结果:%s',$result);
5.时间处理,打印前一天的时间
echo strtotime('-1 day');
6.实现字符串截取无乱码
mb_substr( string $str, int $start[, int $length = NULL[, string $encoding = mb_internal_encoding()]] ) : string
7.获取当前执行脚本的路径包括参数
echo 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'];
echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
8.PHP描述冒泡排序
function bubbleSort($array) {
$size = count($array);
if ($size <= 0) return false;
for ($i = 0; $i < $size; $i++) {
for ($j = $size - 1; $j > $i; $j--) {
if ($array[$j] < $array[$j - 1]) {
$tmp = $array[$j];
$array[$j] = $array[$j - 1];
$array[$j - 1] = $array[$j];
}
}
}
return $array;
}
9.PHP描述快速排序
function quickSort($arr) {
if (count($arr) > 1) {
$k = $arr[0];
$x = $y = [];
$size = count($arr);
for ($i = 1; $i < $size; $i++) {
if ($arr[$i] <= $k) {
$x[] = $arr[$i];
} else {
$y[] = $arr[$i];
}
}
$x = quickSort($x);
$y = quickSort($y);
return array_merge($x, $y);
} else {
return $arr;
}
}
10.PHP描述插入排序
function insertSort($array) {
$size = count($array);
for ($i = 1; $i < $size; $i++) {
$tmp = $array[$i];
$j = $i - 1;
while($array[$j] > $tmp) {
$array[$j + 1] = $array[$j];
$array[$j] = $tmp;
$j--;
}
}
return $array;
}
11.PHP描述选择排序
function selectSort($array) {
$size = count($array);
for ($i = 0; $i < $size; $i++) {
$k = $i;
for ($j = $i + 1; $j < $size; $j++) {
if ($array[$k] > $array[$j]) $k = $j;
}
if ($k != $i) {
$tmp = $array[$i];
$array[$i] = $array[$k];
$array[k] = $tmp;
}
}
return $array;
}
12.PHP描述顺序查找
function sequenceSearch($array, $falgValue) {
foreach ($array as $key => $value) {
if ($value == $falgValue) {
return $key;
}
}
return false;
}
13.PHP描述二分查找
function binSearch($array, $minKey, $maxKey, $value) {
if ($minKey <= $maxKey) {
$key = intval(($minKey + $maxKey) / 2);
if ($array[$key] == $value) {
return $key;
} elseif($array[$key] < $value) {
return binSearch($array, $key + 1, $maxKey, $value);
} else {
return binSearch($array, $minKey, $key - 1, $value);
}
} else {
return false;
}
}
14.二位数组排序算法
function arrayMultiSort($array, $filed, $order = false)
{
if (!is_array($array)) return false;
$keysValue = [];
foreach ($array as $key => $value) {
$keysValue[$key] = $value[$filed];
}
if (!$order) {
asort($keysValue);
} else {
arsort($keysValue);
}
reset($keysValue);
$keySort = [];
foreach ($keysValue as $key => $value) {
$keySort[$key] = $key;
}
$newArr = [];
foreach ($keySort as $key => $value) {
$newArr[$key] = $array[$value];
}
return $newArr;
}
15.求3值最大值的函数(最少代码)
function($a, $b, $c) {
return $a > $b ? ($a > $c ? $a : $c) : ($b > $c ? $b : $c);
}
|