PHP笔试易入雷区

基础篇

1.写出如下程序的输出结果

<?php 
    $test = ‘aaaaaa’;
    $abc = & $test;
    unset($test);
    echo $abc;

输出结果是“aaaaaa”分析如下:
首先PHP内置有一种规则是:当有两个变量同时指向一个内存地址时,这时若其中一个被销毁,但另一个仍然指向该地址。那么内存中存放的数据不会被回收机制处理。因此仍然输入aaaaaa。

网上别人的理解:

因为变量abc引用的是指向aaaaa的路径,而不是引用变量text本身。就好比路径是钥匙的话。现在$abc是配的钥匙, aaaaaa是门后面的内容。现在你毁坏了原装的钥匙,但是门后面的内容,和配的钥匙是不变的。因为还有变量指向aaaaaa,所以aaaaaa也不会被php回收机制销毁。

2.写出如下程序的输出结果

<?php
$count = 5;
function get_count(){
  static $count = 0;
  return $count++;
}
echo $count;
echo get_count();
echo get_count();
?>

上方代码答案是:5 0 1 。重点分析后两个:由于在函数内定义的是静态变量count,因此每次函数结束之后仍能保持原来的值。又由于是return $count++,所以第一次返回的是0,之后再在之前的基础上加一。

3.$GLOBALS[‘a’]与global ¥a的区别

<?php
$GLOBALS['var1']=5;
$var2=1;
function get_value(){
    global $var2;
    $var1 = 0;
    return $var2++;
}
get_value();
echo $var1;  // 5
echo $var2; // 2
?>
<?php
$var1 = 1;
$var2 = 2;

function test(){
    global $var1, $var2;
    $var2 = &$var1;
    echo $var2;
    $var2 = 'snsgou.com';
}

test(); // 输出 1
echo $var2; // 输出 2
echo $var1; // 输出 snsgou.com
?>

分析:global 其实是将全局变量 var1 和 var2 的引用赋给了局部变量 var1,var2,而后 全局变量 var1 的引用又赋给了局部变量 var2,因此局部变量 var2 的改变会影响到全局变量 va1。

$a = "hello";

function test()
{
    global $a;
    $a = "huang";
    echo $a;
}

echo $a;

test();

echo $a;

结果:hello huang huang
解析:第一个输出hello,毋庸置疑,因为函数体还没有执行;第二个输出是在函数体内的输出,由于使用了 global 关键字,将 $a 申明为了全局变量,因此函数内的局部变量 a 会被覆盖,自然是输出 huang,最后一个通过函数申明全局变量的方式改变了外面的 a ,因此也是输出 huang。

4.下面输出结果是多少?

$arr = array(0=>1,"aa"=>2, 3, 4);  
foreach($arr as $key=>$val){  
    print($key == "aa" ? 5 : $val);  
}  

结果:5534
解析:遍历每一个元素的key看等不等于aa,等于就用5替代。当我告诉你答案是5534的时候,你会不会有点惊讶!难道0等于”aa”吗?是的,0就等于”aa”,这道题重点就考你这个。在PHP中两个值进行逻辑判断时,如果两个值的类型不一致PHP会自动把右边的值转换到左边的类型,然后再进行判断。因此”aa”转换整形等于0,自然也就等于左边的0了。
延伸思考:如果将 $key == “aa” 换成 ==“2aa”呢?结果又是如何。

5.请指出下面结果

$a = 3;  
$b = 5;  
if($a = 5 || $b = 7) {  
    $a++;  
    $b++;  
}  
echo $a . " " . $b;  

结果:1 6
解析:执行结果是多少?如果你回答 6 8 or 4 6 or 6 6,那你就掉入陷阱了。
第一个陷阱,认为答案等于 4 6 。估计你粗心把 a = 5 ||b = 7 看成 a == 5 ||b == 7 ,这是新手常犯的错误。
第二个陷阱,认为答案等于 6 8。 你识破了 a = 5 ||b = 7 这个骗局,但你没有注意到,逻辑或里只要依次执行直到某个表达式结果为true,表达式后边的就不再执行,a = 5 返回true,后边的b=7就不执行了。
第三个陷阱,认为答案等于 6 6。 OK,你识破了 逻辑或的规则,于是a=5执行,b=7不执行,但是你没有考虑到这里是逻辑表达式,返回给a的值是要转换为布尔值的。这样看。 所以经过以上三个陷阱,你应该知道答案是多少了,其实a等于true以后,echo a 输出就是1 ,b值不变,结果就是 1 6 。
解题方法:熟悉运算符的优先级,通过()来协助理解程序执行顺序。

6.输出结果

$a = count ("567")  + count(null) + count(false);  
echo $a;  

结果:2
解析:如果你回答 3 or 1,恭喜,掉入陷阱了。
因为count(null)等于0,false也算一个值。所以count(false)等于1。

数组篇

数组作为 php 8大基本数据类型之一,其重要性不言而喻。下面将列举一些数组定义及使用过程中需要注意的地方。

a.以下情况数组键类型会发生强制转化:

包含有合法整型值的字符串会被转换为整型。例如键名 “8” 实际会被储存为 8。但是 “08” 则不会强制转换,因为其不是一个合法的十进制数值。
浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
Null 会被转换为空字符串,即键名 null 实际会被储存为 “”。
b.清空数组后键值问题:

直接上例子

$arr = [32,232,11,32,'dff'];

foreach ($arr as $key => $value) {
    unset($arr[$key]);
}

$arr[] = 4;
print_r($arr);
/*Array
(
    [5] => 4
)*/

先思考一下,为什么键是从5开始呢?正常人的理解大概是数组清空后,再去将这个数组添加新元素,键会从0开始,但是结果并非如此。来看一下官方文档的说明:

如果给出方括号但没有指定键名,则取当前最大整数索引值,新的键名将是该值加上 1(但是最小为 0)。如果当前还没有整数索引,则键名将为 0。注意这里所使用的最大整数键名不一定当前就在数组中。它只要在上次数组重新生成索引后曾经存在过就行了
重点在最后一句话:注意这里所使用的最大整数键名不一定当前就在数组中。它只要在上次数组重新生成索引后曾经存在过就行了。

因此如果想重新从0开始索引,可以直接 unset($arr) ,或者使用 array_values() 新建一个数组。

算法篇

二、算法题

  1. 使用 PHP 描述冒泡排序和快速排序算法,对象可以是一个数组
    //冒泡排序(数组排序)
function bubble_sort($array)
{
$count = count($array);
if ($count <= 0) return false;
    for($i=0; $i<$count; $i++){
        for($j=$count-1; $j>$i; $j--){
        if ($array[$j] < $array[$j-1]){
            $tmp = $array[$j];
            $array[$j] = $array[$j-1];
            $array[$j-1] = $tmp;
            }
        }
    }
    return $array;
}

开发过程中遇到的真实案例
这个需求大概是这样的:前端要求接口返回的数据是按照二维数组中的某一个值来排序的(就比如代金券列表按照卡券减免金额从低到高排序)。之前是使用了 array_multisort 函数实现的。后面发现完全可以用冒泡排序代替啊。一个类似的 demo 如下:

function arr_bobble_sort($arr)
{
    if(!is_array($arr)) {
        throw new Exception('参数必须是数组类型');
    }

    $length = count($arr);

    for ($i=0;$i<$length;$i++) {
        for ($j=$length-1;$j>$i;$j--) {
            if(strlen($arr[$j]['name']) > strlen($arr[$j-1]['name'])) {
                $temp = $arr[$j];
                $arr[$j] = $arr[$j-1];
                $arr[$j-1] = $temp;
            }
        }
    }
    return $arr;
}

$cars = array
(
    array('id'=>3,'name'=>'12345'),
    array('id'=>4,'name'=>'123'),
    array('id'=>5,'name'=>'12345645454'),
    array('id'=>6,'name'=>'1145asd')
);

print_r(arr_bobble_sort($cars));

解析:这是一个需要按照二维数组名称 name 长度排序的案例,只需要修改一下交换条件即可。这样就实现了用冒泡排序完成根据二维数组某个值大小来排序的需求了。

//快速排序(数组排序)

function quick_sort($array) {
    if (count($array) <= 1) return $array;
    $key = $array[0];
    $left_arr = array();
    $right_arr = array();
    for ($i=1; $i<count($array); $i++){
        if ($array[$i] <= $key)
        $left_arr[] = $array[$i];
        else
        $right_arr[] = $array[$i];
    }
    $left_arr = quick_sort($left_arr);
    $right_arr = quick_sort($right_arr);
    return array_merge($left_arr, array($key), $right_arr);
}

注意,for 循环的 $i 的初始值是1,因为是拿数组第一的值作为参考点的。。(每次都写成0 ) : )

2 .使用 PHP 描述顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,
对象可以是一个有序数组
//二分查找(数组里查找某个元素)

function bin_sch($array, $low, $high, $k){
    if ($low <= $high){
        $mid = intval(($low+$high)/2);
        if ($array[$mid] == $k){
            return $mid;
        }elseif ($k < $array[$mid]){
            return bin_sch($array, $low, $mid-1, $k);
        }else{
            return bin_sch($array, $mid+1, $high, $k);
        }
    }
    return -1;
}

//顺序查找(数组里查找某个元素)

function seq_sch($array, $n, $k){
    $array[$n] = $k;
    for($i=0; $i<$n; $i++){
        if($array[$i]==$k){
            break;
        }
    }
    if ($i<$n){
        return $i;
    }else{
        return -1;
    }
}

3 . 写一个二维数组排序算法函数,能够具有通用性,可以调用 php 内置函数
//二维数组排序, arr是数据,arr是数据,keys 是排序的健值,$order 是排序规则,1 是升序,0是降序

function array_sort($arr, $keys, $order=0) {
    if (!is_array($arr)) {
        return false;
    }
    $keysvalue = array();
    foreach($arr as $key => $val) {
        $keysvalue[$key] = $val[$keys];
    }
    if($order == 0){
        asort($keysvalue);
    }else {
        arsort($keysvalue);
    }
    reset($keysvalue);
    foreach($keysvalue as $key => $vals) {
        $keysort[$key] = $key;
    }
    $new_array = array();
    foreach($keysort as $key => $val) {
        $new_array[$key] = $arr[$val];
    }
    return $new_array;
}

当我们用echo指令输出布尔类型时,如果是true则输出的是1,false则什么也不输出。我们可以使用var_dump函数,获取它真正的数据类型。原文

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354