PHP

PHP

标签(空格分隔): 面试


PHP的引用变量的概念及定义

延伸: PHP引用变量的原理

概念:
在 PHP 中 引用意味着用不同的名字访问同一个变量的内容

定义方式:
使用&符号

PHP引用变量的工作原理

$a=range(0,1000);

//定义变量b,将a变量的值赋值给b
//COW机制 (Copy On Write)
$b=$a;

//对a进行修改才会copy
$a=range(0,1000);

//验证COW机制可以使用函数memory_get_usage()
//在每个表达式后面读取内存量

//而引用赋值不遵从COW机制,永远指向一个内存空间

zval结构体

//zval变量容器
$a=range(0,3);
xdebug_debug_zval('a');

//定义变量b,把a的值赋值给b
$b= $a;
xdebug_debug_zval('a');

//修改a
$a=range(0,3);
xdebug_debug_zval('a');

unset 对引用变量的影响

unset只会取消引用,不会销毁空间

$a=1;
$b=&$a;

unset($b);

echo $a."\n";  //此时$a还存在值,证明只是取消$b的引用

对象不会复制空间,不遵守COW
对象本身就是引用传递

class Person{
    public $name='zhangsan';
}

$p1=new Person;
xdebug_debug_zval('p1');

$p2=$p1;
xdebug_debug_zval('p1');

$p2->name='lisi';
xdebug_debug_zval('p1'); //此时并没有开辟出一个新空间,clone对象才可以

真题

//真题

/**
 * TODO 写出如下程序的输出结果
 *
 */
$data=['a','b','c'];

foreach($data as $key => $val){
    $val=&$data[$key];
    var_dump($data);
}

var_dump($data);
/**
 * TODO 程序运行时,每一次循环结束后变量$data的值是什么?请解释
 * TODO 程序执行完成后,变量$data的值是什么?请解释
 */

常量及数据类型考点

PHP中字符串可以使用哪三种定义方法以及各自的区别是什么?

  1. 定义方式: 单引号,双引号,heredoc和nowdoc

heredoc 和 nowdoc (看看)

$a='sdsd';

$str="abcdsd '{$a}'"; //会被解析变量,并且单引号会原样输出
echo $str;

单引号比双引号更快,建议写单引号

  • heredoc类似双引号
  • nowdoc类似双引号
  • 两者都是用来处理大文本

知识点延伸

  1. 数据类型考点
    • 8 大 3 类
    • 标量,复合,特殊
  2. 浮点类型
    • 浮点类型不能运用到比较运算中[???],感觉是比较运算当做判断条件

      $a=0.1;
      

$b=0.5;

    echo $a+$b.PHP_EOL;

    $c=$a+$b == 0.6 ? true:false;

var_dump($c); //为true,不知道为什么
```

    ```php
    $a=0.1;

$b=0.7;
if($a+$b == 0.8) { //用于条件判断时出错
echo 'haha';
}else{
echo '5555';
}
```

  1. 比较浮点类型可以用php内置函数 bccomp()

  2. 布尔值

    • false: 0,0.0,'','0',false,array(),null
  3. 数组类型:

    • 超全局数组:
      $GLOBALS,$_GET, $_POST,$_REQUEST,$_SESSION,$_COOKIE,$_SERVER,$_FILES,$_ENV
  4. NULL

    • 三种情况: 直接赋值为null,未定义的变量,unset销毁的变量

常量

  1. 预定义常量

    • _FILE,_LINE,_DIR,_FUNCTION,_CLASS,_TRAIT,_METHOD,_NAMESPACE
  2. 定义方式
    const,define

const更快,是语言结构
define是函数

  1. define不能用于类常量的定义,const可以

  2. 常量一经定义,不能被修改,不能被删除

真题

用PHP写出显示客户端IP与服务器IP的代码
FILE表示什么意思?

运算符

foo()和@foo()之间区别

  1. 考点:PHP的运算符的错误控制符@
  2. 延伸:
    • PHP所有运算符考点
    • 运算符的优先级
    • 比较运算符
    • 递增递减运算符
    • 逻辑运算符

PHP的错误运算符

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

延伸考点: PHP运算符优先级

递增/递减 > ! > 算数运算符 > 大小比较 > (不)相等比较 > 引用 > 位运算符(^) > 位运算符(|) > 逻辑与 > 逻辑或 > 三目 > 赋值 > and > xor > or

  • 括号的使用可以增加代码可读性

延伸考点: 比较运算符

  1. == 和 === 的区别
  2. 等值判断(FALSE的七种情况) ==> 前面说过布尔值那里

延伸考点: 递增/递减运算符

  1. 递增/递减运算符不影响布尔值 ==> ++/-- 不改变布尔值
  2. 递减NULL值没有效果
  3. 递增NULL值为1
  4. 递增和递减在前就先运算符后返回,反之就先返回,后运算

延伸考点: 逻辑运算符

  1. 短路作用
  2. || 和 && 与 or和and 的优先级不同
$a=true || $b === 3; //短路作用
$b=false && $a===1;

//比较运算符 优先级问题
$a = false || true; //返回true
$b = false or true; //返回false

流程控制考点

真题: 请列出三种PHP数组循环操作的语法,并注明各个循环的区别

  1. for
  2. foreach
  3. while,list(),each()组合循环

for循环只能遍历索引数组,foreach可以遍历索引和关联数组.
联合使用list(),each()和while循环同样可以遍历索引和关联数组


while,list(),each()组合不会reset(),即指针不会重置
foreach遍历会对数组进行reset()操作

延伸考点: PHP分支结构

  1. if ... else if
    • 在elseif语句中只能有一个表达式为true,即在elseif语句中只能有一个语句块被执行,多个elseif从句是排斥关系
    • 使用elseif 语句有一个基本原则,总把优先范围小的条件放在前面处理
  1. switch...case...
    • 和if不同的是,switch后面的控制表达式的数据类型只能是整型,浮点类型或者字符串
    • continue语句作用到switch的作用类似于break跳出switch外的循环,可以使用continue 2
    • switch ... case 会生成跳转表,直接跳转到对应case
    • 效率: 如果条件比一个简单的比较要复杂的多或者在一个很多次的循环中,那么用switch语句可能快一点

真题: PHP中如何优化多个if...elseif语句的情况?

自定义函数及内部函数

考点:

  1. 变量的作用于和静态变量

延伸: 函数的参数及参数的引用传递
: 函数的返回值及引用返回
: 外部文件的导入

变量的作用域

  • 变量的作用域也称变量的范围,变量的范围即它定义的上下文背景(也是它的生效范围).
  • 大部分的PHP变量只有一个单独的范围.
  • 这个单独的范围跨度同样包含了include和require引入的文件
//写出如下程序的输出结果
$count=5;
function get_count(){
    static $count; //静态变量 此时无赋值,则为null
    return $count++;    //null++ ==> 1
}

echo $count;    
++$count;

echo get_count();
echo get_count();

考点:
变量的作用域和静态变量

  • 延伸: 函数的参数及参数的引用传递
  • 延伸: 函数的返回值及引用返回
  • 延伸: 外部文件的导入
  • 延伸: 系统内置函数
$outer='str';
function mgfunc()
{   
    //全局变量引入到函数体内部使用,用关键字global
    global $outer;
    //或者
    $GLOBALS['outer'] //也可以
    echo $outer;
}

静态变量

静态变量仅在局部函数中存在,但当程序执行离开此作用域时,其值并不会消失

static关键字

  1. 仅初始化一次
  2. 初始化时需要赋值
  3. 每执行函数该值会保留
  4. static修饰的变量是局部的,仅在函数内部有效
  5. 可以记录函数的调用次数,从而可以在某些条件下终止递归
function get_count()
{
    static $count; //只初始化一次
    return $count++;
}

echo get_count(); //null
echo get_count(); //1
echo get_count(); //2

延伸考点: 函数的返回值

  • 值通过使用可选的返回语句(return)返回可以返回包括数组和对象的任意类型
  • 返回语句会终止函数执行,将控制权交回函数调用处
  • 省略return,返回值为null,不可有多个返回值

延伸考点: 函数的引用返回

从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用运算符 &

function &myFunc()
{
    static $b=10;
    return $b;
}

$a=myFunc();
$a=&myFunc();
$a=100;
echo myFunc(); //100

延伸考点: 外部文件的导入

  • include/require 语句包含并运行制定文件
  • 如果给出路径名按照路径来找,否则从include_path中查找
  • 如果include_path中也没有,则从调用脚本文件所在目录和当前工作目录下寻找
  • 当一个文件被包含时,其中所包含的代码继承了include所在行的变量范围
  • 加载过程中未找到文件则include结构会发出一个警告;这一点和require不同,后者会发出一个致命错误

require在出错时会产生E_COMPILE_ERROR 级别错误.
换句话讲将导致脚本终止而include只会产生警告(E_WARNING),脚本会继续运行
require(include)/require_once(include_once)唯一区别是PHP会检查该文件是否已经被包含过,如果是则不会再次包含

延伸考点: 系统内置函数

  • 时间日期函数:

    date(),strtotime(),mktime(),time(),microtime(),date_default_timezone_set()

  • IP处理函数:

    ip2long(),long2ip()

  • 打印处理:

    print(),printf(),print_r(),echo,sprintf(),var_dump(),var_export()

  • 序列化及反序列化函数:

    serialize(),unserialize()

  • 字符串处理函数:

    implode(),explode(),join(),strrev(),trim(),ltrim(),rtrim(),strstr(),number_format()...

  • 数组处理函数:

    array_keys(),array_values(),array_diff(),array_intersect(),array_merge(),array_shif(),
    array_unshift(),array_pop(),array_push(),sort()...

解题方法:

着重记忆PHP函数的定义相关内容,理解变量作用域,静态变量,函数的参数和返回值的相关内容,重点记忆我们总结的内置函数

//真题
$var1=5;
$var2=10;

function foo(&$my_var)
{
    global $var1;
    $var1 +=2;
    $var2 =4;
    $my_var+=3;
    return $var2;
}

$my_var=5;
echo foo($my_var)."\n";

echo $my_var."\n";
echo $var1;
echo $var2;
$bar='foo';
$my_var=10;
echo $bar($my_var)."\n";

你可能感兴趣的:(PHP)