• PHP 问题集(一)


    1. PHP 变量的作用域

    参见 php 手册: Language Reference - Variables - Variable scope

    <?php
    $a = 1; /* global scope */ 
    
    function test()
    { 
        echo $a; /* reference to local scope variable */ 
    } 
    
    test();
    ?> 

    在 C 语言中,变量的作用域是从声明到文件结束,所以会误以为能输出 a 的值。

    但是,和 C 语言的全局变量不同,php的全局变量必须在函数体内进行声明。

    PHP 中声明全局变量的方式:

    • 使用 global 关键字: 表明本变量是全局的,而非local。 

    可以在函数体外使用global,场景:文件A中,在函数体外使用了global。文件B包含A,这是合法的。

    <?php
    $a = 1;
    $b = 2;
    
    function Sum()
    {
        global $a, $b;
    
        $b = $a + $b;
    } 
    
    Sum();
    echo $b;
    ?> 
    • 使用 $GLOBALS 数组: $GLOBALS属于superglobal,superglobal 在函数体内不需要global声明,就能任意使用,比如 $_POST。
    <?php
    $a = 1;
    $b = 2;
    
    function Sum()
    {
        $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
    } 
    
    Sum();
    echo $b;
    ?> 
    • 使用static关键字:

    a) 只能在函数内使用

    b) 通过表达式给static变量赋值会造成parse错误

    递归中使用static
    <?php
    function test()
    {
        static $count = 0;
    
        $count++;
        echo $count;
        if ($count < 10) {
            test();
        }
        $count--;
    }
    ?> 

    2. preg_match_all 的返回值研究

    int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )

    先前只知道match是一个二维数组,一直用$matches[0] 在读取所有匹配的内容。

    今天 print_r($matches) 时看到还有$matches[1]和$matches[2],遂决定了解清楚。

    缺省情况下,$flags 值为 PREG_PATTERN_ORDER。对应的:

    Orders results so that $matches[0] is an array of full pattern matches, $matches[1] is an array of strings matched by the first parenthesized subpattern, and so on.

     $matches[1]表示第一个括号中匹配到的内容,$matches[2]。。。等依次存储匹配到的内容。

    我们知道,使用正则表达式的 后向引用 可以很容易的获取匹配到的内容:

    <?php
    
    $str = 'foobar: 2008';
    
    preg_match('/(?P<name>\w+): (?P<digit>\d+)/', $str, $matches);
    
    /* This also works in PHP 5.2.2 (PCRE 7.0) and later, however 
     * the above form is recommended for backwards compatibility */
    // preg_match('/(?<name>\w+): (?<digit>\d+)/', $str, $matches);
    
    print_r($matches);
    
    ?> 
    输出结果为:
    
    Array
    (
        [0] => foobar: 2008
        [name] => foobar
        [1] => foobar
        [digit] => 2008
        [2] => 2008
    )

    那为什么不都使用 后向引用 来进行精确存储呢?

    在PHP手册preg_match函数的changelog写到:

    5.2.2 Named subpatterns now accept the syntax (?<name>) and (?'name') as well as (?P<name>). Previous versions accepted only (?P<name>).  

    也就是从PHP V5.2.2 之后才支持这种写法。而$matches[n] 是最先支持的。

    因此,$matches[n] 更通用。

    3. 实现一个简单的正则表达式引擎

    http://regexpal.com/ 

    题目要求:

    Write a parser for a simplified regular expression

    On an alphabet set [a-z], a simplified regular expression is much simpler than the normal regular expression.

    It has only two meta characters: '.' and '*'.

    '.' -- exact one arbitrary character match.

    '*' -- zero or more arbitrary character match.

    --------------------------

    举个例子,表达式 ab.*d 能匹配 'abcd', 'abccd', 'abad'. 不能匹配'abc', ' '(空字符串), 'abd'.

    两年前,绿盟科技笔试题最后一题即为此。

    这里先放上别人的解决方案,过两天再看:代码之美——30行代码实现正则表达式匹配器

     1 /*match :在text中查找regexp*/
     2 int match(char *regexp,char *text)
     3 {
     4  if(regexp[0] == '^')
     5   return matchhere(regexp+1,text);
     6  do{ /*即使字符串为空也必须检查*/
     7   if (matchhere(regexp,text))
     8    return 1;
     9  }while (*text++!= '\0');
    10  return 0;
    11 }
    12 /*matchhere在text的开头查找regexp*/
    13 int matchhere(char *regexp,char *text)
    14 {
    15  if (regexp[0] == '\0')
    16   return 1;
    17  if (regexp[1] == '*')
    18   return matchstar(regexp[0],regexp+2,text);
    19  if (regexp[0] == '$' && regexp[1]=='\0')
    20   return *text == '\0';
    21  if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
    22   return matchhere(regexp+1,text+1);
    23  return 0;
    24 }
    25 /*matchstar :在text的开头查找C*regexp*/
    26 int matchstar (int c,char *regexp,char *text)
    27 {
    28  do { /*通配符*匹配零个或多个实例*/
    29   if (matchhere(regexp,text))
    30    return 1;
    31  }while (*text!='\0' && (*text++ ==c || c== '.'));
    32  return 0;
    33 }
  • 相关阅读:
    C++对象之间的赋值运算符
    WebService--导出excel并将excel发送到邮箱
    jakarta-oro-2.0.8.jar-----------JAVA FTP相关
    排序函数sort用法简介
    2013年第四届蓝桥杯全国软件大赛本科A组c++预赛 题目及参考答案
    2012年第三届蓝桥杯全国软件大赛c++预赛 题目及参考答案
    数论学习小记 其之三 Gcd与Lcm
    平面分割问题小结
    数论学习小记 其之二 同余及常用数论定理
    数论学习小记 其之一 基础数学
  • 原文地址:https://www.cnblogs.com/handt/p/2670697.html
Copyright © 2020-2023  润新知