PHP Notes

  • PHP 中的所有函数和类都具有全局作用域,而且函数和类可以在其声明之前调用,即函数和类声明会被提到作用域顶部(hoisted)。(注意:如果函数是定义在其他文件中,则必须先require进来而且require必须在调用之前。)而且嵌套的函数可以访问外围函数。下面这段代码是可以正确运行的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
foo();
function foo() {
echo "Hello World!";
}

$bar = new Bar();
echo $bar->a;

class Bar {
public $a = 1;
}
?>
//输出 Hello World!1

再看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
function out($value='25')
{
echo "$value<br />";
}

function test() {
function inner() {
echo "I am inner function<br />";
function innermost() {
out();
inner();
}
innermost();
}

inner();
}

test();
?>
/***
输出结果为:
I am inner function
25
I am inner function
*/
  • 静态变量可以分为:

1.静态全局变量,PHP中的全局变量也可以理解为静态全局变量,因为除非明确unset释放,在程序运行过程中始终存在。

2.静态局部变量,也就是在函数内定义的静态变量,函数在执行时对变量的操作会保持到下一次函数被调用。

3.静态成员变量,这是在类中定义的静态变量,和实例变量相对应,静态成员变量可以在所有实例中共享。

最常见的是静态局部变量及静态成员变量。局部变量只有在函数执行时才会存在。 通常,当一个函数执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。 当下一次执行该过程时,它的所有局部变量将重新初始化。如果某个局部变量定义为静态的, 则它的值不会在函数调用结束后释放,而是继续保留变量的值。

来看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
function &test() {
static $a = 1;
return ++$a;
}
$b = &test();
echo $b; //2
echo test(); //3
$b = 10;
$c = test();
echo $c; //11
echo $b; //11

/*
static变量在函数内部只初始化一次,而且函数执行完毕后其值不会释放。第一次调用test()时返回值为2,
所以echo $b显示2;第二次调用test()时则返回3;如果将$b的值改为10,注意函数test()前有个&符号,
在PHP中表示引用,变量$b是函数test()的引用,所以当$b的值改变时,它将改变return那个变量($a)的初始值,
所以返回11;函数调用也会改变$b的值,所以$b变为11。(注:如果返回值是个表达式则$b不会影响其值)
*/
?>
  • exit()/die()用于中止脚本的执行。

即脚本执行到exit()或die()那一行为止,如果在被包含文件中使用exit()或die(),则同时会中断包含文件的脚本执行。(但在exit()或die()之后声明的函数或类则可以被调用,因为它们会被hoisted到作用域顶部,见上面)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
test.php:
<?php
echo 1;
test();
$b = new Bar();
echo $b->a;
require 'test1.php';
echo 5;

function test()
{
echo "hello";
}

/**
*
*/
class Bar {
public $a = 9;
}

?>

test1.php:
<?php
echo 2;
require 'test2.php';
echo 4;
?>

test2.php
<?php
echo 3;
exit("Nothing!");
?>

/*显示结果为:1hello923Nothing!*/
  • 声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。

  • urlencode()和rawurlencode()

返回字符串,此字符串中除了-_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,urlencode()将空格则编码为加号(+),而rawurlencode()将空格编码为%20
在编码时应该只对部分URL编码,否则URL中的冒号和反斜杠也会被转义。

  • htmlentities 与 htmlspecialchars 的差別

两者都会转换以下符号:

& (ampersand) : &amp;

" (double quote) : &quot;

'(single quote) : '&#039; 或者 &apos;

<(less than) : &lt;

>(greater than) : &gt;

  • htmlspecialchars 只转换以上的 HTML 符号
  • htmlentities 除了转换以上的 HTML 符号, 也转换中文
  • 两者都不会转换英文、数字、括号及分号
  • htmlspecialchars 速度比 htmlentities 快

  • 静态成员变量通过继承在子类和父类中共享,子类可以改变父类中静态变量的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class foo
{
public static $id = 1;
}

class bar extends foo
{

}

echo foo::$id; // 1
echo bar::$id; // 1

bar::$id = 2;

echo foo::$id; // 2
echo bar::$id; // 2
?>
  • PHP_INI_* 模式的定义

PHP_INI_USER 可在用户脚本(例如 ini_set())或 Windows 注册表(自 PHP 5.3 起)以及 .user.ini 中设定
PHP_INI_PERDIR 可在 php.ini,.htaccess 或 httpd.conf 中设定
PHP_INI_SYSTEM 可在 php.ini 或 httpd.conf 中设定
PHP_INI_ALL 可在任何地方设定