Skip to main content

职生涯第5次php面试记录

· 7 min read
wuchuheng

刚面试回来。就结果来说,10道题目只答对了2道确实很尴尬的结果。面试官很清楚自己要问什么 ,也很有耐心,反观我这边在 自己介绍这块说了一堆让人插不下话的废话确实失礼。可是要怎么说才好呢?唉! 整个过程下来30分钟,人家有给提示是自己没把 握到点,给人一种“我想拉你一把,可你不给力”的样子。虽然他问的iffor的流程控制时,一时间我就怀疑他在耍我,这 不废话吗。小学生都能回答的事, 居然问了,结果小学生真的比我强,for 也有不用花括号的写法,而我回答不上。尴尬啊, 黑历史诞生了!!! 好,现在来复盘:

1, 流程控制符不用花括号的写法。

tip

刚才开始也闹不明白为什么非要不用花括号的写法,结合面试官说的“模板引擎”这个关键词回忆下,在使用框架的时候模板 的时候,html混合php的时候就是用这种替代写法,感觉更像是一种html的默认写法规范,

//  if 流程控制
if (expr) :
// ... do sth
elseif (expr):
// ... do sth
else :
// ... do sth
endif;

// for 流程控制
for ($i = 1; $i <= 3; $i++) :
print($i) . PHP_EOL;
endfor;

// foreach 流程控制
foreach([1,2,3] as $v) :
print($v) . PHP_EOL;
endforeach;

// while 流程控制
$i = 1;
while ($i <= 10):
print $i;
$i++;
endwhile;

// 其它
swithc(expr) {
case 'foot' :
// do sth ;
break;
case
...
default:
...
}
endswitch

2,关于数组比较运算符 === 和 ==

var_dump(['a'=>1, 'b'=>2] === ['b'=>2, 'a'=>1]);  // 顺序不一致 false
var_dump(['a'=>1, 'b'=>2] === [ 'a'=>1, 'b'=>2]); // 值和排序一致 true

var_dump(['a'=>1, 'b'=>2] == ['b'=>2, 'a'=>1]); // 值一致不要求顺序一致 true

3, 代码复用trait

trait 代码复用这个之前用过,不过面试时没及时想起来,很尴尬。现在再折腾下吧。 既然要折腾那就找个方向吧,官方文档说了,trait 可以解除php类的单继承限制,那么这个解除单继承 能不能理解为其它在类里use复用一个代码块其实就是继承一个类呢,而trait其实可以看作一个类呢? 就先这样假设吧? 那既然trait是个类,那么就应该拥有类的特有的魔术方法。

    //  在trait 和类同时使用 构造方法和析构方法
Trait TraitA
{
public $foo;

// traitA赋值 $foo
public function __construct()
{
$this->foo = 'to set value by TraitA';
}
}

class Test
{
use TraitA;
// 类如果上面的TraitA不执行构造方法,那本就赋值
public function __construct()
{
$this->foo = $this->foo ?? 'to set value TestClass';

}
}

print (new Test())->foo . PHP_EOL; // 打印 to set value TestClass

结果很透明 Test类覆盖了 TraitA的方法,从而修改的foo参数,这不类继承和覆盖一样的吗? 所以当下估且可以把trait看作是一个类,毕竟还有其的魔术方法还没测试。 好,下一步来看看,复用2个 trait,并写起冲突的方法。看看怎么样。

//  在trait 和类同时使用 构造方法和析构方法
Trait TraitA
{
public $foo;

// traitA赋值 $foo
public function __construct()
{
$this->foo = 'to set value by TraitA';
}
}

Trait TraitB
{
public $foo;

// traitA赋值 $foo
public function __construct()
{
$this->foo = 'to set value by TraitA';
}
}

class Test
{
use TraitA, TraitB;
}

print (new Test())->foo . PHP_EOL; // PHP Fatal error: Trait method __construct has not been applied, because there are collisions with other trait methods on Test in /home/http/tmp/tmp.php on line 25

结果还是报错了,果然这点会起冲突跟类的单例继承不一样。也可能是多类该有的现象。后面再观察下吧。

4, 方法内的static关键字

这个知识点以前学习过,不过忘记了。所以这个不意外,真回答不了。 staticself都是对当前类的引用,不过self比较死板,self写在哪个类就代表哪个类, 如果哪个类刚好有可以调用的方法和属性就调用,没有就报错,哪怕你在当前类把没有属性补充上也没用。 而staticself一样,不过灵活很多,用static调用东西,它会一由本类往上游的继承的方向找,直到 找到要调用的方法然后就调用。找不到就报错误。

class A
{
public static function testStatic() { static::printClassName(); }
public static function testSelf() { self::printClassName(); }
public static function printClassName() { print 'A' . PHP_EOL; }
}

class B extends A
{
public static function printClassName() { print 'B' . PHP_EOL; }
}
B::testStatic(); // print B
B::testSelf(); // print A

5 抽象类

6 接口

7 把对象当参数传到方法有什么不同

8 php 内置引擎模板和rquire

9 php 匿名的使用