PHP5学习笔记
C方式:
/**/ 这是一个C风格的注释 *它可以跨越多行 *直到关闭标记
C++方式:
// 这是一个C++风格的注释,它在行的末尾结束
Shell方式:
# 这是一个Shell风格的注释,它在行的末尾结束
- 变量不需要声明直接使用,可以自动改变类型,用 $ 标志当变量名的前缀
- 主脚本中定义的变量,若在函数中使用,需要 $GLOBALS[] 方式引用
- 不支持全局变量,除了预定义的超全局变量:
超全局变量 | 说明 | ||
$_GET[] | 包含所有PHP从客户浏览器接收的GET参数的数组,包括通过URL发送的数据 | ||
$_POST[] | 包含所有PHP从客户浏览器接收的POST参数的数组 | ||
_REQUEST | 包含所有请求参数的数组 | ||
$_COOKIE[] | 包含所有PHP从客户浏览器接收的cookies的数组 | ||
$_ENV[] | 包含环境变量的数组 | ||
$_SERVER[] | 存放服务器变量的数组
|
||
$_SESSION | 存放会话变量的数组 |
在PHP5中,允许在声明函数时,为对象、接口、数组或者callable类型的入参强制声明类型。对于字符串、整型等标量类型,不支持类型提示:
1 2 |
class Person {} function sayHello (Person $p, $times) {} |
1 2 3 |
$name = "John"; $$name = "Registered user"; // $$$var 这样的形式也是可能的 print $John; // 打印:Registered user |
1 2 3 4 5 6 |
isset() // 用来判断某个变量是否已经被PHP声明。它返回一个布尔型的值 isset($arr["offset"]) // 如果$arr或者$obj["offset"]没有声明,则返回false isset($obj->property) // 如果$obj或者$obj->property没有声明,则返回false isset{$varl, $var2, $var3); // 如果所有变量均声明,则返回true unset() // 可以取消定义之前定义的变量,如没有其他变量在引用它则释放内存 empty() // 可以用来检查一个变量是否没被声明或者值是false |
1 2 3 4 |
$x = 5985; $x = - 345; $x = 0x8C; // 十六进制数 $x = 047; // 八进制数 |
值范围与C编译器double类型有关,可以使用科学计数法:
1 2 3 |
$x = 10.365; $x = 2.4e3; $x = 8E-5; |
表示逻辑的真假,可以取值 true 或者 false 。
数据类型 | false值 | true值 |
整型 | 0 | 所有非零值 |
浮点型 | 0.0 | 所有非零值 |
字符串 | ""、"0" | 所有其他字符串 |
NULL | 总是 | 总不 |
数组 | 如果不含任何元素 | 含有一个以上元素 |
对象 | 总不 | 总是 |
资源 | 总不 | 总是 |
字符序列,自动地用null做结束的组合,与C字符串不一样的是,不需要以null符号计算其长度。字符串有三种表示方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#双引号界定的字符串:支持嵌入变量或者表达式,以及转义字符: $str = "Hello,$user_name.\""; $str = "The array offset $i contains $arr[$i]"; #单引号界定的字符串:不支持变量嵌入,仅支持'、\这两个字符的转义 $str = 'Hello, World'; $str = 'Today\'s the day'; #定界符界定的字符串:转义和嵌入变量的支持类似于"",但是不需要转义" $str = <<<DEMINITER Hello There DEMINITER #访问单个字符,索引从0开始 $c = $str{0}; |
一个键/值对的集合,索引可以是整数或者字符串,值可以是任意类型:
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
// 声明关联数组 $arr = array( 'key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3' ); // 声明索引数组,等价于 array(0 => 'a', 1 => 'b') array( 'a', 'b' ); // 声明索引数组,等价于 array(1 => "ONE", 2 => "TWO", 3 => "THREE" ) array( 1 => "ONE", "TWO", "THREE" ); // 访问数组元素 $arr[key]; // 获得数组长度 $c = count($arr); // 通过数字索引遍历数组 $cars = array( "Volvo", "BMW" ); $arrlength = count($cars); for ($x = 0; $x < $arrlength; $x ++) { echo $cars[$x]; } // 通过foreach遍历数组: foreach($array as [$key => ] [&] $value) {} // 举例: $user = array( "Bill" => "35", "Steve" => "37", "Peter" => "43" ); foreach ($user as $name => $age) { echo "User " . $name . "'s age is " . $age; } $nums = [0, 1, 2]; $ass = array( 'k0' => 0, 'k1' => 1, 'k2' => 2 ); # 可以把关联数组转换为索引数组 print_r(array_values($ass)); # 删除一个元素,但是不改变剩余元素的索引 unset($nums[1]); # [ 0, 2 ] unset($ass['k1']); # { k0 => 0, k2 = > 2 } $nums = [1, 2, 3, 4, 5, 6]; # 切片操作,获得一个子数组 $sub = array_slice($nums, 1, 3); # [2, 3, 4],源数组不变 # diff操作,根据值过滤,生成一个新数组,所有元素索引不变 $sub = array_diff($nums, [3, 4]); # [1, 2, 4=>5, 5=>6] # differ操作,根据key过滤,生成一个新数组,所有元素索引不变 # 注意第二个参数:key可以写为字符串,自动转换为索引数字;value则随意 $sub = array_diff_key($nums, [3 => null, '4' => null]); # [1, 2, 3, 5=>6] # 删除若干元素,并且reindex array_splice($nums, 1, 3); # 返回值也是 [2, 3, 4],但是源数组也被修改:[1, 5, 6] |
索引为整数的数组,也称为索引数组;索引为字符串的数组,也称为关联数组。
这一特殊类型用于表示变量“没有值”, null 是该类型唯一的有效值。
一经定义,全局可用,不能在新的函数、PHP文件中重新声明他们,声明语法:
1 |
define("CONSTANT_NAME", value [, case-sensitivity]); |
运算符 | 名称 | 结合性 | 说明 |
new | 创建对象 | 无 | 创建新的对象 |
[] | 数组元素操控 | 右 | 读写数组的元素 |
! | 逻辑否 | 右 | 后续表达式为true,则整个表达式为false |
~ | 按位否 | 右 | 如果是数字操作数,得到的是操作数 按位非的结果(浮点值会被先转变为 整型值)如果是字符串,将得到相同长度并且每个字符都是原来字符接位非的新的字符串 |
++ | 递增 | 右 | 将变量的值增加1,包括$var++ ++$var两种 |
-- | 递减 | 右 | 将变量的值减小1 ,包括$var-- --$var两种 |
(type) | 强制转型 | 右 | 包括: (int) (integer) (float) (real) (double)(string) (bool) (Boolean) (array) (object) |
@ | 错误抑制 | 右 | 把表达式求值过程中的错误忽略掉 |
* / % + - | 算术运算符 | 左 | %为取模:两个操作数都被转变成整型,结果是第一个操作数 除第二个操作数余数 |
. | 字符串连接 | 左 | 处理字符串的连接,非字符串会自动转换 |
<< | 按位左移 | 左 | 按位左移,移出的丢弃,右侧补0 |
>> | 按位右移 | 左 | 按位右移,移出的丢弃,左侧补0 |
< <= | 小于(等于) | 无 | 逻辑运算,返回布尔值,字符串按字典序比较 |
> >= | 大于(等于) | 无 | |
== | 等于 | 无 | |
!= <> | 不等于 | 无 | |
=== | 全等于 | 无 | ===与==相似,但是操作的数据类型必须匹配。不执行自动转换类型:例如1===”1″返回 false |
!== | 不全等于 | 无 | |
& | 按位与 | 左 | 除非两个给定的参数都是字符串,否则参数将被转换到相应的整型数,然后再执行按位与运算 |
^ | 按位异或 | 左 | 除非两个给定的参数都是字符串,否则参数将被转换到相应的整型数,然后再执行按位异或运算 |
| | 按位或 | 左 | 除非两个给定的参数都是字符串,否则参教将被转换到相应的整型数,然后再执行按位或运算 |
&& | 逻辑与 | 左 | 短路,如果操作数1为false |
|| | 逻辑或 | 左 | 短路,如果操作数1为true |
?: | 三目运算符 | 左 | |
= | 赋值 | 左 | 将右操作数的值赋给左边的变量 |
=& | 引用赋值 | 左 | 相当于别名 |
+= -= *= /= .=%= &= |= ^= ~=<<= >>= | 带操作的赋值 | 左 | 先执行指定的计算,在把计算结果赋给左值 |
and | 逻辑与 | 左 | 类似上面的逻辑运算符,只是优先级更低 |
xor | 逻辑异或 | 左 | |
or | 逻辑或 | 左 | |
, | 列表操作符 | 左 |
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 |
#C风格语法 if (expr) statement elseif (expr) statement elseif (expr) statement else statement #Pascal风格语法 if (expr): statement list elseif (expr): statement list else if (expr): statement list else: statement list endif; #举例 <!--?php if ($num < 0): ?--> $num is negative<!--注意:HTML不会替换变量--> <!--?php elseif{$num == 0): ?--> $num is zero <!--?php elseif{$num --> 0): ?> $num is positive <!--?php endif; ?--> |
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 |
#C风格语法 switch (expr){ case expr: statement list case expr: statement list default: statement list } #Pascal风格语法 switch (expr): case expr: statement list break;#可以使用break跳出switch结构 case expr: statement list default: statement list endswitch; #举例 switch ($answer) { case 'y': case 'Y': print "The answer was yes\n"; break; case 'n': case 'N': print "The answer was no\n"; break; default: #如果没有匹配的,default语句被执行 print "Error: $answer is not a valid answer\n"; break; } |
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 |
#C风格的while循环 while(expr) statement #Pascal风格的while循环 while(expr): statementlist endwhile; #举例 $result = 1; while ($n > 0) { $result *= $n--; break;#用于跳出循环,break 1和break同义,表示跳出一层循环,类推,switch纳入计算 } print "The result is $result"; #do-while循环 do{ statement }while(expr); #C风格的for循环 for (expr, expr,…; expr,expr, …; expr,expr,…) statement #Pascal风格的for循环 for (expr, expr,…; expr,expr, …; expr,expr,…): statementlist endfor; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#error_code.php <?php $OK = 0; $ERROR = 1; ?> #test.php <?php include "error_code.php"; print("$OK"); #include支持相对、绝对路径,动态合成绝对路径: include $_SERVER [ "DOCUMENT_ROOT"]."/script.php"; #include遇到文件不存在的情况,会继续执行,要终止执行,可以使用require require "import.php"; ?> #include_once、require_once保证只会包含进来一次 |
函数作用域:默认情况下,函数外部定义的变量,不能在函数内部访问,使用 $GLOBALS[var_name] 可以提取并访问全局作用域的变量。 global 关键字可以引入全局变量到函数内部:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#函数声明语法 function function_name (argl, arg2, arg3,…){ statement list } #声明函数时,函数名加&前缀,则按引用方式传递返回值 function &ret_by_ref ($n){ } #声明函数时,参数名加&前缀,则按引用方式传递参数 function &arg_by_ref (&$n,$default = 0){ #支持设置参数的默认值 static times = 0;#支持静态函数变量 } #函数调用语法 function_name (argl, arg2, arg3,…); #global用法示例 global $varl, $var2,...; function func{) global $var; $var = 2; } $var = 1;func(); print $var;#打印2 |
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
class Person { function __construct($name) { $this->name = $name; } function getName() { #方法执行时,PHP自动生成$this变量 return $this->name; } private $name; public $dob; }; $alex = new Person('Alex'); print $alex -> getName();#使用->操作符访问对象成员 print $alex -> dob;#注意,访问属性不要加$前缀 #public/private/protected访问修饰符,针对对象中的方法和属性: #PHP4的var声明还是支持的 class MyClass { private $id = 18; public function getld() { return $this->id;} } #统一构造函数名__construct (): class MyClass { function __construct{) { print "Inside constructor"; } } #统一析构函数名:__destruct(): class MyClass { function __destruct() { print "Destroying object"; } } #instanceof 操作符PHP4的is_a()函数不推荐使用: if ($obj instanceof Circle) { print '$obj is a Circle';} #final标记方法 Final关键字允许你用来标识方法,使其不能被子类重载: class MyClass { final function getBaseClassName(){}; } #final标记类,声明一个类为final类型后,它将不能被继承 final class FinalClass {} class BogusClass extends FinalClass {}//错误 #强制复制对象,为了克隆一个对象,必须使用clone关键字 class MyClass { function __clone() { print "Object is being cloned"; } $obj = new MyClass(); $obj_copy = clone $obj; #类定义中现在包含常量,而且可以用类来引用: class MyClass { const SUCCESS = const FAILURE = "Success"; } print MyClass::SUCCESS; #静态方法。静态方法不支持$this变量, 因为它们并没有绑定到任何具体的对象: class MyClass { static function helloWorld { print "Hello, world";} } MyClass::helloWorld(); #静态成员,可以通过类自身来访问 class Singleton { static private $instance = NULL; private function __construct{} {} static public function getlnstanceO { if (self::$instance == NULL) { self::$instance = new SingletonO; return self::$instance; } } #抽象类。把类声明为抽象类可以防止它被实例化。但是你可以继承一个抽象类: abstract class MyBaseClass { function display() { print "Default display routine being called"; } } #抽象方法。把方法声明为抽象的,以便在继承的子类中再去定义。包含抽象方法的类本身必须是一个抽象类: abstract class MyBaseClass { abstract function display(); } #对象类型提示 #函数声明中可以对参数进行对象类型提示。如果函数调用的时候没有传递正确的对象类型,系统报错: function expectsMyClass(MyCiass $obj) {} #多态:使用parent::来调用父类的方法,使用slef::调用当前类的静态方法 class Child extends Ancestor { const NAME = "Child"; function __construct(){ parent::__construct(); print self::NAME; } } #__toString()函数,类似于Java的toString() #foreach迭代对象属性,类似于数组迭代 $obj = new Class(); foreach($obj as $key => $val){ } #实现接口Iterator可以修改迭代行为 |
1 2 3 4 5 6 7 8 9 |
#接口声明语法 interface IA { function m();#不能给原型函数设置访问限定符 } interface IB extends IA,I{ } #实现接口的语法 class A implements B, C, ... { } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#try-catch语法 try { #会抛出一个异常的代码 throw new object();#只能抛出一个Exception类或其子类的实例 } catch (FirstExceptionClass $exception) { #异常处理代码 } catch (SecondExceptionClass $exception) { #异常处理代码 } #Exception类的结构 class Exception { function __construct([$message [,$code]]); final public getMessage(); final public getCode(); final public getFile(); final public getLine(); final public getTrace(); final public getTraceAsString(); } |
1 2 3 4 5 6 |
<?php function _autoload($class_name) { require__once ($_SERVER ["DOCUMENT_ROOT"] . "/classes/$class_name.php"; } ?> |
1 2 3 4 5 |
<?php #这是标准嵌入方法 ?> <?/*短代码,某些环境会关闭*/?> <?=$var?> #等价于<?php echo($var)?> |
开发期可以设置error_reporting=E_ALL & E_STRICT。通过设置log_errors/display_errors可以控制错误信息的流向,日志文件的位置可以通过error_log指定。可以指定全局错误处理函数:
1 2 3 |
#type为错误类型,可以是:E_NOTICE、E_WARNING、E_USER_NOTICE、E_USER_WARNING、E_USER_ERROR #error为错误文本 error_function($type, $error, $file, $line); |
1 2 3 4 5 6 |
<?php ob_start();//开启输出缓冲,若不开启,则无法正确写入响应头 //设置Cookie,参数依次:cookie名称、值、过期时间、作用范围,作用范围可以是blog.gmem.cc、.gmem.cc这样的形式 //删除Cookie,只需要将值设为'',并过期即可 setcookie('uid', $uid, time()+3600, '/' ); ?> |
每一个会话使用Session ID识别,该ID由客户端IP、当前时间、一些附加信息散列处理得到
1 2 3 4 5 6 7 8 9 10 |
<?php ini_set('session.use_cookies',1); ini_set('session.use_only_cookies',1); session_start();#必须紧跟ini_set后调用,创建一个session ID,并使用空$_SESSION初始化会话 $_SESSION['uid'] = $uid; header('Location:/index');//重定向 #销毁会话 $_SESSION = array(); session_destroy(); ?> |
函数名 | 描述 | ||
|
打开一个连向MySQL服务器的连接. 参数:主机名(string)、用户名(string)、密码(string)、数据库名(string)、TCP端口 (integer) | ||
|
用mysqli_real_connect初始化MySQLi并且返回一个对象 设置不同的连接选项 打开一个连向MySQL服务器的连接 |
||
|
关闭一个MySQL数据库连接,参数是连接对象(函数方式) | ||
|
最后一次失败的连接的错误号 | ||
|
最后一次失败的连接的错误信息 | ||
|
返回数据库连接描述信息的字符串 | ||
|
发送一个SQL语句并获得结果集对象,参数:连接(函数方式),SQL,模式(缓冲否) | ||
|
一次发送并处理多个查询 | ||
|
抓取结果集行的方式:数组、关联数组、对象 | ||
|
预编译语句相关的函数prepare:准备一个预编译语句,参数:(连接),SQL语句bind_result:绑定变量到结果集,参数:(语句),变量bind_param:绑定变量到语句,参数:(语句),类型,变量。类型包括:s字符串,i数字,d双字节浮点数,b=blob
execute:执行语句 stmt_fetch:获取数据到输出变量中 stmt_close:关闭预编译语句 |
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 38 |
<?php $conn = mysqli_connect("localhost", "username", "passwd", "dbname"); if (empty($conn)) { die("mysqli connect failed: " . mysqli_connect_error()); } // 另外一种风格 $mysqli = new mysqli("localhost", "username", "passwd", "dbname"); $mysqli->close(); // 设置参数 $mysqli = mysqli_init(); $mysqli->options(MYSQLI_INIT_CMD, "SET_AUTOCOMMIT=0"); // 置初始参数 $mysqli->options(MYSQLI_READ_DEFAULT_FILE, "SSL_CLIENT"); $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); // 超时的秒数 $mysqli->real_connect("localhost", "username", "username", "dbname"); // 执行查询 $result = $conn->query("SELECT * FROM T_USER", MYSQLI_USE_RESULT); // 二个参数表示使用无缓冲 while ($row = $result->fetch_row()) { print $row[0]; } $result->free(); // 关闭结果集 // 预编译语句, $stmt = $conn->prepare("INSERT INTO T_USER VALUES(?, ?)"); #绑定输入参数 $stmt->bind_param($name, $dob, $age); $name = "Alex";$dob = "1986";$age = "29"; $stmt->execute(); $name = "Meng";$dob = "1989";$age = "26"; $stmt->execute(); #绑定输出变量 $stmt->bind_result($name,$dob,$age); while ($stmt->fetch()) { print "$name: $dob"; } #处理BLOG数据的方式和普通数据一样 ?> |
支持大多数的数据库,提供统一风格的API
类型 | 说明 |
编程错误 | 语法错误:在PHP执行前被检测到,例如:
Parse error: parse error in test.php on line 4 Include/Require:错误之后的代码被废弃,得到不完整编译的文件(后续代码未定义) |
未定义符号 | 未定义变量、常量:错误通常以警告形式出现 未定义函数、类:中止执行,例如: Fatal error: Call to undefined function: undefined_this_function_is() |
通用类错误 | php.ini的配置差异:使用ini_get()检查 SAPI差异:例如Apache专有函数 |
运行时错误 | 通常不是编程错误,例如硬盘故障、网络故障。由错误报告机制或者异常处理机制负责处理 |
错误级别 | 说明 |
E_ERROR | 严重的不可恢复的错误,例如内存不足、类重复声明 |
E_WARNING | 例如数据库连接失败、除0错误 |
E_PARSE | 该错误在编译时发生,会强制PHP在执行前退出 |
E_NOTICE | 一般性通知,建议开发期开启 |
E_CORE_ERROR | 该内部PHP错误是由于扩展启动失败导致的,而且会导致PHP运行退出 |
E_USER_ERROR | 用户生成的致命错误,可以通过 trigger_error() 生成 |
E_USER_WARNING | 用户生成的警告,可以通过trigger_error() 生成 |
E_USER_NOTICE | 用户生成的一般性通知,可以通过trigger_error() 生成 |
E_ALL | 所有错误和警告,除级别 E_STRICT 以外 |
php.ini的一些配置项控制哪些错误显示,以及如何显示:
配置项 | 数据类型 | 说明 |
error_reporting | 整型 | 设置默认错误报告方式,例如:E_ALL,E_ALL & ~E_NOTICE(除了NOTICE级别的所有错误被报告)。0表示任何错误都不报告 |
display_errors | 布尔型 | 控制错误是否作为PHP输出的一部分显示出来。它默认设置为On |
display_startup_errors | 布尔型 | 这个设置控制在PHP启动时是否显示错误。它的默认设置是Off |
error_prepend_string | 字符串 | 这个字符串将在浏览器中显示错误信息之前直接显示出来 |
error_append_string | 字符串 | 这个字符串将在浏览器中显示错误信息之后直接显示出来 |
track_errors | 布尔型 | 开启时,$php_errormsg在脚本中可见,包含错误信息 |
html_errors | 布尔型 | 是否在错误信息中采用HTML格式,默认On,CLI版本PHP除外 |
xmlrpc_errors | 布尔型 | 错误信息是否作为XML-RPC故障显示 |
xmlrpc_error_number | 整型 | 配合xmlrpc_errors |
log_errors | 布尔型 | 是否记录错误日志到文件系统,默认记录到Web服务器的错误日志中 |
error_log | 字符串 | 日志文件的位置,指定syslog则记录到系统日志(Unix) |
log_errors_max_len | 整型 | 日志信息最大长度,超过的被截断 |
ignore_repeated_errors | 布尔型 | 重复的错误是否被显示 |
ignore_repeated_source | 布尔型 | 来自同一文件同一行的错误是否被显示 |
配置文件样例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
; 开发环境的典型配置 error_reporting = E_ALL display_errors = on html_errors = on log_errors = off ; 生产环境的典型配置 error_reporting = E_ALL & ~E_NOTICE display_errors = off log_errors = on html_errors = off error_log = "/var/log/php-error.log" ignore_repeated_errors = on ignore_repeated_source = on |
可以定义一个函数,在每一个错误出现时调用:
1 2 3 4 5 6 7 |
function customErrorHandler ($errno, $errstr) { echo "<b>Error:</b> [$errno] $errstr<br />"; echo "Ending Script"; die(); } set_error_handler("customErrorHandler"); |
在语句前加上符号@,则该语句的错误级别为0。只有内置的错误报告和日志记录受@影响,自定义错误处理器继续工作:
1 2 3 4 5 |
<?php if (@$_GET["id"]) { $obj = new MyDataObject(); } ?> |
PEAR组件使用单独的错误机制,通过检查返回值来判断异常。
PHP5提供了新的,面向对象的try-catch机制来捕获和处理异常,异常必须是Exception类的子类型。下面的代码示例了异常的常规用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function checkAge ($age) { if ($age < 0) { // 抛出异常 throw new Exception('Invalid age.'); } } // 捕获异常 try { checkAge(- 2); } catch (Exception $e) { echo 'Error: ' . $e->getMessage(); } // 自定义异常类 class InvalidAgeException extends Exception { public function setMessage ($message) { $this . $message = $message; } } |
任何未捕获的异常,可以由顶层异常处理器负责处理:
1 2 3 4 5 6 7 8 |
function customExceptionHandler ($exception) { echo "Exception: " . $exception->getMessage(); } // 设置处理器 set_exception_handler('customExceptionHandler'); // 下面的异常没有被捕获,讲传递给顶层异常处理器 throw new Exception('Uncaught Exception occurred'); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!--?php $xml = xml_parser_create('UTF-8'); // XML编码方式 xml_set_element_handler($xml, 'start_handler', 'end_handler'); // 开始、结束标签处理器 xml_set_character_data_handler($xml, 'character_handler'); // 文本内容处理器 xml_parser_set_option($xml, XML_0PTION_CASE_FOLDING, false); // 禁用标签名全大写转换 function start_handler ($xml, $tag, $attributes) { global $level; // 标签嵌套层次 echo " \n" . str_repeat(' ', $level) . " $tag"; foreach ($attributes as $key =--> $value) { echo "$key $value"; } $level ++; } function end_handler ($xml, $tag) { global $level; $level --; echo str_repeat(' ', $level, ' ') . " $tag"; } function character_handler ($xml, $data) {} xml_parse($xmly, file_get_contents("test.xml")); // 执行解析 ?> |
该方式的缺点是内存消耗大
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php $dom = new DomDocument(); $dom->load('test.xml'); $root = $dom->documentElement; process_children($root); function process_children ($node) { $children = $node->childNodes; foreach ($children as $elem) { if ($elem->nodeType == XML_TEXT_NODE) { if (strlen(trim($elem->nodeValue))) { echo trim($elem->nodeValue), "\n"; } } else if ($elem->nodeType == XML_ELEMENT_NODE) { process_children($elem); } } } ?> |
SimpleXML扩展在PHP5默认开启,该方式处理XML最简单,直接通过数据结构的形式访问XML节点:
1、属性导航表示子元素的迭代器,例如:mother->children得到孩子的迭代器
2、数字索引表示第N个子元素,例如:mother->children[1]访问第二个孩子
3、非数字索引表示XML属性,例如:mother['name']得到母亲的名字
4、元素可以直接作为字符串使用(_toString),以访问其文本内容(不包括子元素)
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 |
<?php $sx0 = simplexml_load_file('test.xml'); // 通过文件读取 $sx1 = simplexml_load_dom(new DomDocument()); // 通过DOM对象读取 $str = <<<XML <?xml version='1.0'?> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>XML</title> </head> <body bgcolor="#FFF"> <div>Hello <span>XML</span></div> <div></div> </body> </html> XML; $html = simplexml_load_string($str); // 从字符串读取 foreach ($html->body->div as $div) { $div->span[0]; $div['bgcolor']; echo $div; // 输出文本内容 echo strip_tags($div->asXML()); // 输出完整文本 } file_put_contents('test.xml', $html->asXML()); ?> |
Leave a Reply