php 面试归纳

文章目录

echo 、print、print_r 的区别:

  • echo 是 语言结构,可以输出一个或者多个字符串,无返回值。
  • print 是语言结构,只接受一个字符串,有返回值。
  • print_r() 是函数,可以打印出多种类型变量的值(如数组,对象)

魔术常量

名称含义
__LINE__文件中的当前行号。
__FILE__文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
__DIR__文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。
__FUNCTION__函数名称
__CLASS__类的名称
__TRAIT__Trait 的名字,Trait 名包括其被声明的作用区域(例如 Foo\Bar)。
__METHOD__类的方法名
__NAMESPACE__当前命名空间的名称(区分大小写)。

session 与 cookie 的区别:

类型Cookiesession
存储位置浏览器端服务器端
安全性
大小限制没有
数据类型字符串全部
有效期使用长时间存储几乎不做持久化

详解:

GET 与 POST 请求的区别:

GET 与 POST 请求的区别

strlen( )与 mb_strlen( )的作用分别是什么

相同点:

strlenmb _strlen 都是用于获取字符串长度的

不同点:

strlen 只针对单字节编码字符,也就是说它计算的是字符串的总字节数,如果是多字节编码,如 gbk 和 utf8,使用 strlen 得到的不是字符的个数,而是该字符的总字节数,可以使用 mb_strlen 指定字符集获取其字符个数

例:


header('content-type:text/html;charset=utf-8');
$str = "我爱我家123";
echo "mb_strlen输出对应编码的字符个数".mb_strlen($str,'utf8')."<br/>";
//当字符属于单字节,也就是在ASCILL(0-255)编码内时,也表示字符个数
echo "strlen输出字节数".strlen($str);

运行结果:

这里写图片描述

实现中文字串截取无乱码的方法。

方法一: 使用 php 内置函数 mb_substr()


header('content-type:text/html;charset=utf-8');
$str = '我爱我家';
echo mb_substr($str,0,2,'utf8');

方法二: 自定义函数,以 utf8 为例,

相关函数:

preg_split — 通过一个正则表达式分隔字符串


array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

array_slice() — 返回根据 offset 和 length 参数所指定的 array 数组中的一段序列。


array array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] )

例:


header('content-type:text/html;charset=utf-8');
$str = "我爱我家123";
function utf8_substr($str,$start,$len){
    return implode(array_slice(preg_split('//u',$str,0,PREG_SPLIT_NO_EMPTY),$start,$len));
}
echo utf8_substr($str,2,3);

运行结果:

这里写图片描述

include 和 require 有什么区别?Include 和include_once 又有什么区别?

include 和 require 有什么区别

用 PHP 打印出前一天的时间格式是 2006-5-10 22:21:21


echo date('Y-m-d H:i:s',time()-3600*24);
echo "<br/>";
echo date('Y-m-d H:i:s',strtotime('-1 day'));

求两个日期的差数,例如 2009-3-1 ~ 2009-4-4 的日期差的天数

<?php
$days=(strtotime('2009-4-4')-strtotime('2009-3-1'))/(3600*24);
echo $days;

不使用第三个变量交换两个变量的值

方法一:


$a = 1;
$b = 2;
list($b,$a) = array($a,$b);
echo '$a的值:'.$a;
echo "<br/>";
echo '$b的值:'.$b;

方法二:(php7以上)

$a = 1;
$b = 2;
[$b,$a] = [$a,$b];
echo '$a的值:'.$a;
echo "<br/>";
echo '$b的值:'.$b;

说明 php 中赋值与引用的区别。什么时候传值什么时候传引用?

区别:

  • 变量赋值: 例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。
  • 引用赋值: 这意味着新的变量简单的引用(换言之,“成为其别名” 或者 “指向”)了原始变量。改动新的变量将影响到原始变量,反之亦然。

使用类型:

  • 使用引用赋值,简单地将一个 & 符号加到将要赋值的变量前。
  • 对象默认是传引用。

sort()、asort()、和 ksort() 有什么分别?它们分别在什么情况下使用?

  • sort():根据数组中元素的值,以英文字母顺序排序,索引键会由 0 到 n-1重新编号。主要是当数组索引键的值无关紧要时用来把数组排序。
  • asort():对数组进行排序,数组的索引保持和单元的关联。主要用于对那些单元顺序很重要的结合数组进行排序。
  • ksort():根据数组中索引键的值,以英文字母顺序排序,特别适合用于希望把索引键排的关联数组

扩展:

  • sort(): 函数用于对数组单元从低到高进行排序。
  • rsort(): 函数用于对数组单元从高到低进行排序
  • asort(): 函数用于对数组单元从低到高进行排序并保持索引关系。
  • arsort(): 函数用于对数组单元从高到低进行排序并保持索引关系。
  • ksort(): 函数用于对数组单元按照键名从低到高进行排序。
  • krsort(): 函数用于对数组单元按照键名从高到低进行排序。

总结:sort的基础上,加上r代表从高到低排序,加a保持索引关系,加k对键名进行排序


写个函数来解决多线程同时读写一个文件的问题。

//打开文件,获取文件的二进制流
$fp = fopen("/tmp/lock.txt","w+");

//判断文件
if(flock($fp, LOCK_EX)){// 进行排它型锁定
	write($fp,"Write something here\n");
	flock($fp, LOCK_UN);// 释放锁定
}else{
	echo "Couldn't lock the file !";
}

fclose($fp);

禁掉cookie的session使用方案,设置session过期的方法,对应函数

  • 通过 url 传值,把session id附加到url上(缺点:整个站点中不能有纯静态页面,因为纯静态页面session id将无法继续传到下一页面)
  • 通过隐藏表单,把session id 放到表单的隐藏文本框中同表单一块提交过去(缺点:不适用<a>标签这种直接跳转的非表单的情况)

直接配置php.ini文件,将php.ini文件里的session.use_trans_sid= 0设为1(不建议使用,session_id容易被劫持),用文件、数据库等形式保存session id,在跨页过程中手动调用

过期时间设置:


//第一种:setcookie() 直接用setcookie设置session id的生命周期。
     $lifetime=60; //保存1分钟 
     session_start(); 
     setcookie(session_name(), session_id(), time()+$lifetime, "/");
     
//第二种:使用session_set_cookie_params()    
     $lifetime=60;//保存1分钟
     session_set_cookie_params($lifetime);
     session_start();
     session_regenerate_id(true);
     
//其中session_regenerate_id();方法用于改变当前session_id的值,并保留session中数组的值。参数默认为 false,如果设置为true则改变session_id的值,并清空当前session数组。

详细:https://blog.csdn.net/change_any_time/article/details/79466405

在 PHP 中 error _reporting 这个函数有什么作用?

error_reporting() 函数能够在运行时设置 error_reporting 指令。 PHP有诸多错误级别,使用该函数可以设置在脚本运行时的级别。 如果没有设置可选参数 levelerror_reporting() 仅会返回当前的错误报告级别。

相关题目: error_reporting(2047) 什么作用?

php.ini中错误级别都有设置对应的常量值,而2047是多个常量值的总和(2047 = 1 + 2 + 4 + 8 + 16 + 32 +64 + 128 + 256 + 512 + 1024),意味着这当中每个常量值的对应的错误级别都将被显示。

扩展:


// 关闭所有PHP错误报告
error_reporting(0);

// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// 报告 E_NOTICE也挺好 (报告未初始化的变量
// 或者捕获变量名的错误拼写)
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);

// 除了 E_NOTICE,报告其他所有错误
error_reporting(E_ALL ^ E_NOTICE);

// 报告所有 PHP 错误 (参见 changelog)
error_reporting(E_ALL);

// 报告所有 PHP 错误
error_reporting(-1);

// 和 error_reporting(E_ALL); 一样
ini_set('error_reporting', E_ALL);

错误级别和常量值对应关系

php魔术方法

类方法:

  • __construct():具有构造函数的类会在每次创建新对象时先调用此方法,适合在使用对象之前做一些初始化工作。如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用
    parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承。
  • __destruct():析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

方法重载:

  • __call():在对象中调用一个不可访问方法时,__call(); 方法会被调用。
  • __callStatic():用静态方式中调用一个不可访问方法时,__callStatic(); 方法会被调用。

属性重载: (只对类中私有受保护的成员属性有效)

  • __get():读取不可访问属性的值时,__get() 会被调用。
  • __set():在给不可访问属性赋值时,__set() 会被调用。
  • __isset():当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
  • __unset():当对不可访问属性调用 unset() 时,__unset() 会被调用。

序列化相关:

  • __sleep():序列化时调用,serialize()
    函数会检查类中是否存在该魔术方法。如果存在,该方法会先被调用,然后才执行序列化操作。
  • __wakeup():unserialize() 会检查是否存在一个 __wakeup()
    方法。如果存在,则会先调用该方法,用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作

操作类和对象方法:

  • __toString():方法用于一个类被当成字符串时调用,例如把一个类当做字符串进行输出
  • __invoke():当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
  • __set_state():当调用 var_export() 导出类时,此静态 方法会被调用。 本方法的唯一参数是一个数组
  • __clone():当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone()
    方法会被调用,可用于修改属性的值。
  • __autoload():该方法可以自动实例化需要的类。当程序要用一个类但没有被实例化时,改方法在指定路径下查找和该类名称相同的文件。否则报错。
  • __debugInfo():php5.6增加的特性,var_dump()一个类时触发,返回一个包含对象属性的数组

写个函数用来对二维数组排序

例:


/**
 * [array_sort1 description]
 * @param  [array] $arr   [二维数组]
 * @param  [str] $colum [要进行比较的列]
 * @param  [str] $type  [类型]
 * @return [array]        [description]
 */
function array_sort($arr,$colum,$type='asc'){
	$new_arr = array();
	foreach($arr as $k=>$v){
		$new_arr[$k] = $v[$colum];
	}
	if($type=='asc'){
		sort($new_arr);
	}else{
		rsort($new_arr);
	}
	foreach($arr as $k=>$v){
		foreach($new_arr as $k1=>$v1){
			if($v[$colum]==$v1){
				$new_arr[$k1] = $v;
			} 
		}
	}
	return $new_arr;

}

$arr = array(
	array('a'=>'dfdf','b'=>'change'),
	array('a'=>'gdgfdf','b'=>'this'),
	array('a'=>'sgdsgfdf','b'=>'world')
);

var_dump(array_sort($arr,'b'));

或者没使用php函数普通排序:

/**
 * [array_sort description]
 * @param  [array] $arr   [二维数组]
 * @param  [str] $type  [类型]
 * @return [array]        [description]
 */
function array_sort($arr,$type='asc'){
	$new_arr = $arr;
	foreach($arr as $k=>$v){
		if(is_array($v)){
			$new_arr[$k] = array_sort($v);
		}else{
			if($type=='asc'){
				foreach($arr as $k1=>$v1){
					if($v>$v1 && $k<$k1){
						list($new_arr[$k],$new_arr[$k1]) = array($new_arr[$k1],$new_arr[$k]);
					} 
				}
			}else{
				foreach($arr as $k1=>$v1){
					if($v<$v1 && $k>$k1){
						list($new_arr[$k],$new_arr[$k1]) = array($new_arr[$k1],$new_arr[$k]);
					} 
				}
			}
			return $new_arr;
		}
	}
	return $new_arr;
	
}
$arr = array(
	array('a'=>'dfdf','b'=>'change'),
	array('a'=>'gdgfdf','b'=>'this'),
	array('a'=>'sgdsgfdf','b'=>'world')
);
var_dump(array_sort($arr,'desc'));die;

php是什么,能用来做什么事情

是什么:

PHP( Hypertext Preprocessor,超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。

能做什么:

PHP 主要是用于服务端的脚本程序,因此可以用 PHP 来完成任何其它的 CGI程序能够完成的工作,例如收集表单数据,生成动态网页,或者发送/接Cookies。但 PHP 的功能远不局限于此。

PHP 脚本主要用于以下三个领域:

    1. 服务端脚本。这是 PHP 最传统,也是最主要的目标领域。
    1. 命令行脚本。可以编写一段 PHP 脚本,并且不需要任何服务器或者浏览器来运行它。通过这种方式,仅仅只需要 PHP 解析器来执行。
    1. 编写桌面应用程序。

如果$a='abcdef' 请取出$a 的值并打印出第一个字母


echo $a{0};
echo $a[0];

相关题目: $string="abcdefg",那么$string{4}的值是?

值是 e

请 写 一 个 函 数 , 实 现 以 下 功 能 : 字 符 串 “open_door” 转 换 成 “OpenDoor


function to_upper($str){
	$arr = explode('_',$str);
	$arr = array_map('ucfirst',$arr);
	return implode($arr);
}

$str = 'open_door';

echo to_upper($str);

要求写一段程序,实现以下数组arr1 转换成数组arr2

这里写图片描述


$arr = array(
	array('fid'=>1,'tid'=>1,'name'=>'name1'),
	array('fid'=>1,'tid'=>2,'name'=>'name2'),
	array('fid'=>1,'tid'=>3,'name'=>'name3'),
	array('fid'=>1,'tid'=>4,'name'=>'name4'),
	array('fid'=>2,'tid'=>7,'name'=>'name5')
);

$tmp_arr = array();
foreach($arr as $k => $v) {
	$tmp_arr[$v['fid']][]=array_slice($v,1);
}

$arr = array();
foreach($tmp_arr as $k => $v) {
	$arr[]=$v;
}

var_dump($arr);

简述单引号和双引号的用法

单引号: 要表达一个单引号自身,需在它的前面加个反斜线(\)来转义。要表达一个反斜线自身,则用两个反斜线(\),其他字符都被当作普通字符处理。

双引号: 会对一些特殊的字符变量进行解析,所以要显示特殊字符,需要反斜线(\)来转义。

简述Heredoc 结构和Nowdoc 结构的区别

  • heredoc 结构类似于双引号字符串,只是单引号不用被转义,heredoc 句法结构:<<<。在该运算符之后要提供一个标识符,然后换行。接下来是字符串 string本身,最后要用前面定义的标识符作为结束标志。

要注意的是结束标识符这行除了可能有一个分号(;)外,绝对不能包含其它字符。这意味着标识符不能缩进,分号的前后也不能有任何空白或制表符。

  • Nowdoc 结构是类似于单引号字符串的。 nowdoc 结构也用和 heredocs 结构一样的标记 <<<,但是跟在后面的标识符要用单引号括起来,即 <<<‘EOT’。Heredoc 结构的所有规则也同样适用于 nowdoc结构,尤其是结束标识符的规则。
    ######简述 GBK、GB2312、BIG5 、GB18030、utf-8
  • GB2312 支持的汉字较少
  • GBK 是相比 GB2312 汉字更为丰富,包括全部中日韩汉字,GBK的文字编码是双字节来表示的,即不论中、英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1。
  • GB18030 相比 GBK 增加了一些少数名族汉字汉字库更为多样
  • UTF-8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。一般简 体中文使用 utf-8而繁体中文使用 BIG5。
    ######以下语句可能存在错误,如果存在错误请指出什么错误(每个语句单独考虑)
print_r $val = 333; // error,print_r 是一个函数,需加上括号,如果是 print 则可以
print_r($val = 333); // 正确
$a += ($b = 4) + 5; // notice,$a 未定义,但可以正确运行
$foo[bar] = 'enemy'; // notice,最好 bar 加上引号
function x($a = "1", $b){} // 无,但给参数默认值应尽量从右向左
写出如下程序的输出结果
<?php
$count = 3;
$count++;
function num_count(){
	static $count=0;
	return $count++;//注意$count++和++$count的区别
}
echo $count;
echo '   ';
echo num_count();
echo '   ';
echo num_count();

这里写图片描述

在 PHP 中,作用域是不重叠的,函数之外的是全局变量,函数内部定义的则是局部变量,二者是两个不同的变量,除非在函数内使用 global显式声明使用全局变量或直接用$_GLOBALS 来引用。
######如何在一个 php 函数中使用具有全局属性的变量,说出两种方式?

global $a 或者 $GLOBALS['a']
字符串怎么转成整数,有几种方法?怎么实现?
    1. 强制类型转换: (整型)字符串变量名;
    1. 直接转换:settype(字符串变量,整型);
    1. intval(字符串变量);
      ######函数中的默认参数位置如何放置?

当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧;否则,函数将不会按照预期的情况工作。

######php是否区分大小写

  • php中的变量和常量是区分大小写的。
  • php中的类名和方法名,甚至一些关键字都是不区分大小写的。
以下代码的执行后是, 值为:
<?php
var_dump(in_array('001',array(1)));

这里写图片描述

以下代码的执行后是,$result 值为:
<?php
var_dump(is_null(''));

这里写图片描述
扩展:

is_null – 检测变量是否为 NULL,如果变量是 null 则返回 TRUE,否则返回 FALSE。
在下列情况下一个变量被认为是 NULL:

  1. 被赋值为 NULL
  2. 尚未被赋值
  3. 被 unset()

请用 PHP代码编写类实现在每次对数据库连接的访问中都只能获得唯一的一个数据库连接(单例模式)


class Mysql(){
	private static $instance;//设置实例属性为私有,防止外界更改

	//设置控制器为私有,禁止new关键字直接实例化该类对象
	private static function __construct(){
		self::$instance=mysqli_connect('localhost','root','root');
	}

	public static function getInstance(){
		if(!self::$instance instanceof self){
			self::$instance = new self;
		}
		return self::$instance;
	}
	//禁止克隆
	private function __clone(){

	}
}

$db = Mysql::getInstance();

php图片验证码无法显示,怎么处理?

  • 查看是否开启gd扩展
  • 查看文件是否加bom头(bom头是字节序标记)
  • 使用ob_clean()清空输出缓冲区

什么方法来加快页面的加载速度

  • 数据库添加索引
  • 只将有用的服务器资源加载进来
  • 打开浏览器的缓存功能,使其可以对静态资源文件进行缓存
  • 使用nosql技术将静态化不需要改变的数据(缓存数据)
  • 使用smarty等模板技术将页面静态化(缓存页面)
  • 图片等大文件单独放在一个服务器,也可以使用阿里云的oss进行存储
  • 使用cdn加速网络资源的请求速度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值