php blob 输出_PHP语法进阶“面试题”

(图文无关)(其实没图)

如果你正在寻找PHP开发的工作,那么提前掌握这些PHP面试题技巧,你就能体会到这是一门多么神奇的语言。这篇文章能使你在求职过程中事倍功半。

我们先从字符串开始:

<?php
error_reporting(E_ALL);
$a = 'abc';
$a[4] = 'e';
var_dump($a);
var_dump(ord($a[3]));

请问这段代码的输出是什么呢?是「abce」、「abc」、「abcx00e」还是报一个E_NOTICE?

答:它的输出是「abc e」,不会报错。少的那个字符被空格(ASCII = 32)补齐了。

那么:

$a[-1] = '0';
var_dump($a);

$a[-100] = 'a';
var_dump($a);

$a[1] = 'abcde';
var_dump($a);

又是什么呢?

字符串过去了,我们再来看看函数调用吧。

我们都知道,PHP的传参有按值传递、通过引用传递两种方式。那么:

<?php
function foo($a)
{
   $a=5;
   echo func_get_arg(0);
}
foo(2);
echo "n";

是多少呢?

只回答2或者5的都不合格:Online PHP editor | output for Nu8Ns

bbc354d52eda4b623344060d31fff928.png

出处:php/php-src

玩玩魔术方法吧:

<?php
class foo {
        public $pp = array('t'=>null);

        function bar() {
                echo $this->t ='faaa';
        }
        function __get($prop)
        {
                return $this->pp[$prop];
        }
        function __set($prop, $val)
        {
                echo "__set";
                $this->pp[$prop] = '';
        }
}
$f = new foo;
$f->bar();

请问它的输出是「__set」吗?如果你回答是的话,那你的面试已经不合格了。它的输出是「__setfaaa」。

当然,这个其实很好理解,直接使用=之后的值可以避免多调用一次__get,算是个“性能优化”手段。

代码出处:php/php-src

再看一段代码:

<?php
class A {
	function __call($strMethod, $arrArgs) {
		echo __CLASS__;
	}
}

class B extends A {
	function __call($strMethod, $arrArgs) {
		echo __CLASS__;
	}

	function test() {
		A::test1(1,'a');
		B::test2(1,'a');
		self::test3(1,'a');
		parent::test4(1,'a');
	}
}

$b = new B();
$b->test();

请问它的输出是「ABBA」吗?其实它的答案是「BBBB」。

这不是Bug,而是feature:When __call() is invoked via ::, ensure current scope's __call() is favoured over the specified class's __call().

代码出处:php/php-src ; 测试:Online PHP editor | output for AclDv

再深入一点,我们一起来学习反射吧。

<?php
class A {
        protected static $static_var='foo';

        public function getStatic(){
           $class = new ReflectionClass($this);
           return $class->getStaticPropertyValue('static_var');
        }

        public function getStatic2(){
            $class = new ReflectionClass($this);
            $staticProps = $class->getStaticProperties();
            return $staticProps['static_var'];
        }

}

class B extends A {
        protected static $static_var='foo2';
} 

请问调用getStaticgetStatic2分别会输出什么?

答案:

getStatic2 = foo2
getStatic = Fatal error: Uncaught ReflectionException: Class B does not have a property named static_var in /in/ENaZW:7

为什么呢?

getStaticPropertyValue会调用zend_std_get_static_property,其会检查当前调用的参数在当前作用域是否可见: https://github.com/php/php-src/blob/ded87a9ea0f12107031e6cac6c0299c1f87ff233/Zend/zend_object_handlers.c#L1466

getStaticProperties则可以直接输出所有参数,不管它是否可见。

代码出处:ReflectionClass::getStaticPropertyValue - Manual

今天我们的面试题就到这里,现在,你学会PHP了吗?

最后,如果你想体验一下谭浩强的乐趣,不如我们一起:

<?php

function f() { return 0; }
$a[0][1] = 'good';
$a[1][1] = 'bad';

echo "n" . '$i=f(): ';
echo $a[$i=f()][++$i];
unset($i);

echo "n" . '$$x=f(): ';
$x='i';
echo $a[$$x=f()][++$$x];
unset($i, $x);

echo "n" . '${'i'}=f(): ';
echo $a[${'i'}=f()][++${'i'}];
unset(${'i'});

echo "n" . '$i[0]=f(): ';
echo $a[$i[0]=f()][++$i[0]];
unset($i);

echo "n" . '$i[0][0]=f(): ';
echo $a[$i[0][0]=f()][++$i[0][0]];
unset($i);

echo "n" . '$i->p=f(): ';
$i = new stdClass;
echo $a[$i->p=f()][++$i->p];
unset($i);

echo "n" . '$i->p->q=f(): ';
$i = new stdClass;
$i->p = new stdClass;
echo $a[$i->p->q=f()][++$i->p->q];
unset($i);

echo "n" . '$i->p[0]=f(): ';
$i = new stdClass;
echo $a[$i->p[0]=f()][++$i->p[0]];
unset($i);

echo "n" . '$i->p[0]->p=f(): ';
$i = new stdClass;
$i->p[0] = new stdClass;
echo $a[$i->p[0]->p=f()][++$i->p[0]->p];
unset($i);

Class C {
	static $p;
}

echo "n" . 'C::$p=f(): ';
echo $a[C::$p=f()][++C::$p];

echo "n" . 'C::$p[0]=f(): ';
C::$p = array();
echo $a[C::$p[0]=f()][++C::$p[0]];

echo "n" . 'C::$p->q=f(): ';
C::$p = new stdclass;
echo $a[C::$p->q=f()][++C::$p->q];

php/php-src

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值