【PHP】高级面试题之十万个为什么?(一)

成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。


这里写图片描述

现在也已经工作三年时间了,PHP在平时工作中天天都会使用,但是内心总是感觉差点什么,觉得自己对PHP这门语言了解的还不够,故下定决心,整理了一下平时工作所学所用,提出各种各样的问题,然后再一一的解决这些问题,加深自己对PHP这门语言的理解!!!

1、substr()、strpos()、strlen()、htmlentities() 处理字符串时依据的编码方式是相同的?

答:不是相同的,substr() 处理中文会乱码

2、如果一个脚本的编码是 ISO-8859-1,则其中的字符串也会被编码为 ISO-8859-1?

答案:是的

3、一个布尔值 Boolean 的 true 被转换成 string 的 “ 1 ”,false 被转换成空字符串?

$boolean_Foo = (boolean)true;
$boolean_Fcc = (boolean)false;  
echo (string)$boolean_Foo;    // echo '1';
echo (string)$boolean_Fcc;    // echo '';

4、PHP的字符串在内部是字节组成的数组,用花括号访问或修改字符串对多字节字符集很不安全?

解析:很多时候我们都使用 PHP字符串 而php字符串是如何组成的呢,这个估计很少人去了解~
其实PHP 字符串就是 字符数组 假设我们定义一个字符串
$string ="hello world";
    //这个字符串是由 h , e , l ,  l , o , 空格 , w ,o,r,l,d 这几个字符组成,我们可以验证一下看看:
    echo $string[1];   //  输出结果是 e

    //扩展:1、那么我们能不能去改变其中的某个值呢?
    $string[1] = "H";
    echo $string;  //  输出结果是 hHllo world

    //2、如何我们将一个位置赋予多个值会怎样呢?
    $string[1] = "HHHHH";
    echo $string;      //  输出结果是 hHllo world 看来PHP做了安全处理

5、“ $@ ”将函数中所有参数当成单个字符串,“ $* ”把函数的所有参数当一个数组?

答:都是取所有参数,前者是存到列表,后者作为一个字符串(原理还不是很理解/(ㄒoㄒ)/~~)

6、PERL风格正则默认的非贪婪模式尽可能少的匹配所搜索的字符串?

答:不是尽可能少,而是尽可能多的匹配所搜索的字符串(详解请参数:PHP -- Perl风格正则表达式)

7、{n,},n是一个非负整数,意思是至少匹配n次; ?等价于匹配长度{0,1} ?

答:{n,} 表示前面的原子出现不少于n次; ?标识前面的原子匹配0次或1次

8、在执行效率上 preg_match 比ereg的速度要略快一些吗?

从执行效率上来对比POSIX风格的ereg和兼容Perl风格的preg_match     
我们都知道ereg是PHP的正则函数,而preg_match 是perl移植过来的, 两者的写法上都有些区别。
现在我们从执行效率上看看两者的区别为了让时间上区别更明显 我们讲函数执行1000次 并对比3次看看他们的区别
public function index(){
    $datetime = "2008-08-03";
    $loopnum = 1000;
    $num  = 5;
    echo "从时间转换来看各函数对字符处理效率:".'<br>';
    for ($k = 0; $k < $num; $k++){
            $time_start = $this->microtime_float();
            for($i = 0; $i < $loopnum; $i++){
                preg_match('/([/d]{4})-([/d]{2})-([/d]{2})/i', $datetime, $outarr);
                $result  = mktime(0, 0, 0, $outarr[2], $outarr[3], $outarr[1]);
            }
            $time_1 = $this->microtime_float();
            for($i = 0; $i < $loopnum; $i++){
                ereg ("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $datetime, $outarr);
                $result  = mktime(0, 0, 0, $outarr[2], $outarr[3], $outarr[1]);
            }
            $time_2 = $this->microtime_float();
            echo "1:preg_match: " . ($time_1 - $time_start) . "  ";echo '<br>';
            echo "2:ereg: " . ($time_2 - $time_1) . "  ";echo '<br>';
            echo '<hr />';
}
}

/**
 *  时间统计函数
 */
function microtime_float($time = null)
{
   list($usec, $sec) = explode(' ', $time ? $time : microtime());
   return ((float)$usec + (float)$sec);
}

实验结果
从时间转换来看各函数对字符处理效率:
1:preg_match: 0.012001037597656
2:ereg: 0.016000986099243


1:preg_match: 0.013000011444092
2:ereg: 0.018000841140747


1:preg_match: 0.012001037597656
2:ereg: 0.017000913619995


1:preg_match: 0.012001037597656
2:ereg: 0.017001152038574


1:preg_match: 0.013000011444092
2:ereg: 0.017000913619995


我们可以看出 在执行效率上 preg_match 还是比ereg的速度好略快一些
实际上在PHP手册中 也有建议说:“注: 使用 Perl 兼容正则表达式语法的 preg_match() 函数通常是比 ereg() 更快的替代方案。可见 PHP也是推荐使用preg_match的

9、POSIX兼容正则没有修正符,PERL兼容正则中可能用到修正符?

答:正则表达式作为一个匹配的模版,是由原子(普通字符,例如a-z),有特殊功能的字符(元字符,例如*、+ 和?等),以及模式修正符三个部分组成。
修正符:
POSIX兼容正则没有修正符。
PERL兼容正则中可能使用的修正符(修正符中的空格和换行被忽略,其它字符会导致错误):
i (PCRE_CASELESS):
匹配时忽略大小写。
m (PCRE_MULTILINE):
当 设定了此修正符,行起始(^)和行结束($)除了匹配整个字符串开头和结束外,还分别匹配其中的换行符(\n)的之后和之前。
s (PCRE_DOTALL):
如 果设定了此修正符,模式中的圆点元字符(.)匹配所有的字符,包括换行符。没有此设定的话,则不包括换行符。
x (PCRE_EXTENDED):
如 果设定了此修正符,模式中的空白字符除了被转义的或在字符类中的以外完全被忽略。
e :
如果设 定了此修正符,preg_replace() 在替换字符串中对逆向引用作正常的替换,将其作为 php 代码求值,并用其结果来替换所搜索的字符串。 只有 preg_replace() 使用此修正符,其它 PCRE 函数将忽略之。
A (PCRE_ANCHORED):
如 果设定了此修正符,模式被强制为“anchored”,即强制仅从目标字符串的开头开始匹配。
D (PCRE_DOLLAR_ENDONLY):
如 果设定了此修正符,模式中的行结束($)仅匹配目标字符串的结尾。没有此选项时,如果最后一个字符是换行符的话,也会被匹配在里面。如果设定了 m 修正符则忽略此选项。
S :
当一个模式将被使用若干次时,为加速匹配起见值得先对其进行分析。 如果设定了此修正符则会进行额外的分析。目前,分析一个模式仅对没有单一固定起始字符的 non-anchored 模式有用。
U (PCRE_UNGREEDY):
使 “?”的默认匹配成为贪婪状态的。
X (PCRE_EXTRA):
模式中的任何反斜线后面跟上 一个没有特殊意义的字母导致一个错误,从而保留此组合以备将来扩充。默认情况下,一个反斜线后面跟一个没有特殊意义的字母被当成该字母本身。
u (PCRE_UTF8):
模 式字符串被当成UTF-8。
注意:
模式修正符(Pattern Modifiersi     -可同时匹配大小写字母
M     -将字符串视为多行
S     -将字符串视为单行,换行符做普通字符看待,使“.”匹配任何字符
X     -模式中的空白忽略不计    
U     -匹配到最近的字符串
e     -将替换的字符串作为表达使用

10、无论是 array(1, 2, 3) 还是array(1 => 2, 2=> 4)等,本质上都是hash_table?

答:在回答这个问题之前,我们需要了解一下什么是hash_table?

Hash Table 是计算机科学中很重要的一种数据结构,其时间复杂度为O(1),主要是通过把关键字Key 映射到数组中的一个位置来访问记录,所以速度相当快。映射函数称为 Hash函数。

Hash Table 的实现步骤是:

1、创建一个固定大小的数组用于存放数据

2、设计良好的 Hash 函数

3、通过 Hash 函数把数据按照关键字 key 映射到数组中的某一个位置,并在此数据上进行数据存取

结论:无论是 array(1, 2, 3) 还是array(1 => 2, 2=> 4)等,本质上都是key=>value形式, array(1, 2, 3),实际上是 array(0=>1,1=> 2, 2=>3),所以它与array(1 => 2, 2=> 4)本质上都是hash_table。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值