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 }
原文地址:https://www.cnblogs.com/handt/p/2670697.html