·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> PHP中文手册2

PHP中文手册2

作者:佚名      php网站开发编辑:admin      更新时间:2022-07-23
php中文手册211.异常处理

用户可以用自定义的异常处理类来扩展 PHP 内置的异常处理类。以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的。译者注:以下这段代码只为说明内置异常处理类的结构,它并不是一段有实际意义的可用代码。

<?phpclassException{PRotected$message='Unknown exception';// 异常信息protected$code=0;// 用户自定义异常代码protected$file;// 发生异常的文件名protected$line;// 发生异常的代码行号function__construct($message=null,$code=0);final functiongetMessage();// 返回异常信息final functiongetCode();// 返回异常代码final functiongetFile();// 返回发生异常的文件名final functiongetLine();// 返回发生异常的代码行号final functiongetTrace();// backtrace() 数组final functiongetTraceAsString();// 已格成化成字符串的 getTrace() 信息/* 可重载的方法 */function__toString();// 可输出的字符串}?>

如果使用自定义的类来扩展内置异常处理类,并且要重新定义构造函数的话,建议同时调用parent::__construct()来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString()并自定义输出的样式。

扩展 PHP 内置的异常处理类

<?php// 自定义一个异常处理类classMyExceptionextendsException{ // 重定义构造器使 message 变为必须被指定的属性 public function__construct($message,$code=0) { // 自定义的代码 // 确保所有变量都被正确赋值 parent::__construct($message,$code);}// 自定义字符串输出的样式public function__toString() { return__CLASS__.": [{$this->code}]:{$this->message}\n";}public functioncustomFunction() { echo"A Custom function for this type of exception\n"; }}//创建一个用于测试异常处理机制的类classTestException{public$var;constTHROW_NONE=0;constTHROW_CUSTOM=1;constTHROW_DEFAULT=2;function__construct($avalue=self::THROW_NONE) {switch ($avalue) {caseself::THROW_CUSTOM:// 抛出自定义异常throw newMyException('1 is an invalid parameter',5);break;caseself::THROW_DEFAULT:// 抛出默认的异常throw newException('2 isnt allowed as a parameter',6);break;default:// 没有异常的情况下,创建一个对象$this->var=$avalue;break;}}}// 例子 1try {$o= newTestException(TestException::THROW_CUSTOM);} catch (MyException $e) {// 捕获异常echo"Caught my exception\n",$e;$e->customFunction();} catch (Exception $e) {// 被忽略echo"Caught Default Exception\n",$e;}// 执行后续代码var_dump($o);echo"\n\n";// 例子 2try {$o= newTestException(TestException::THROW_DEFAULT);} catch (MyException $e) {// 不能匹配异常的种类,被忽略echo"Caught my exception\n",$e;$e->customFunction();} catch (Exception $e) {// 捕获异常echo"Caught Default Exception\n",$e;}// 执行后续代码var_dump($o);echo"\n\n";// 例子 3try {$o= newTestException(TestException::THROW_CUSTOM);} catch (Exception $e) {// 捕获异常echo"Default Exception caught\n",$e;}// 执行后续代码var_dump($o);echo"\n\n";// 例子 4try {$o= newTestException();} catch (Exception $e) {// 没有异常,被忽略echo"Default Exception caught\n",$e;}// 执行后续代码var_dump($o);echo"\n\n";?>12.生成器

生成器允许你在foreach代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要yield多次,以便生成需要迭代的值。

<?phpfunctionxrange($start,$limit,$step=1) { if ($start<$limit) { if ($step<=0) { throw newLogicException('Step must be +ve');} for ($i=$start;$i<=$limit;$i+=$step) { yield$i; } } else { if ($step>=0) { throw newLogicException('Step must be -ve'); } for ($i=$start;$i>=$limit;$i+=$step) { yield$i; } }}/* Note that both range() and xrange() result in the same* output below. */echo'Single digit odd numbers from range(): ';foreach (range(1,9,2) as$number) { echo"$number";}echo"\n";echo'Single digit odd numbers from xrange(): ';foreach (xrange(1,9,2) as$number) { echo"$number";}?>
Single digit odd numbers from range():  1 3 5 7 9 Single digit odd numbers from xrange(): 1 3 5 7 9 
Comparing generators withIteratorobjects

The primary advantage of generators is their simplicity. Much less boilerplate code has to be written compared to implementing anIteratorclass, and the code is generally much more readable. For example, the following function and class are equivalent:

<?phpfunctiongetLinesFromFile($fileName) { if (!$fileHandle=fopen($fileName,'r')) { return;}while (false!==$line=fgets($fileHandle)) { yield$line;}fclose($fileHandle);}// versus...classLineIteratorimplementsIterator{ protected$fileHandle; protected$line; protected$i; public function__construct($fileName) { if (!$this->fileHandle=fopen($fileName,'r')) { throw newRuntimeException('Couldn\'t open file "'.$fileName.'"'); } } public functionrewind() { fseek($this->fileHandle,0); $this->line=fgets($this->fileHandle); $this->i=0; } public functionvalid() { returnfalse!==$this->line; } public functioncurrent() { return$this->line; } public functionkey() { return$this->i; } public functionnext() { if (false!==$this->line) { $this->line=fgets($this->fileHandle); $this->i++; } } public function__destruct() { fclose($this->fileHandle); } }?>13.引用<?php$a=&$b; //这意味着$a$b指向了同一个变量。$a$b在这里是完全相同的,这并不是$a指向了$b或者· //相反,而是$a$b指向了同一个地方。?>

如果具有引用的数组被拷贝,其值不会解除引用。对于数组传值给函数也是如此。如果对一个未定义的变量进行引用赋值、引用参数传递或引用返回,则会自动创建该变量。

<?php

functionfoo(&$var) { }

foo($a);// $a is "created" and assigned to null

$b= array();

foo($b['b']);

var_dump(array_key_exists('b',$b));// bool(true)

$c= newStdClass;

foo($c->d);

var_dump(property_exists($c,'d'));// bool(true)

?>

同样的语法可以用在函数中,它返回引用,以及用在new运算符中(PHP 4.0.4 以及以后版本):

<?php$bar=& newfooclass();$foo=&find_var($bar);?>

如果在一个函数内部给一个声明为global的变量赋于一个引用,该引用只在函数内部可见。可以通过使用$GLOBALS数组避免这一点。在函数内引用全局变量:

<?php$var1="Example variable";$var2="";functionglobal_references($use_globals){ global$var1,$var2; if (!$use_globals) { $var2=&$var1;// visible only inside the function } else { $GLOBALS["var2"] =&$var1;// visible also in global context }}global_references(false);echo"var2 is set to '$var2'\n";// var2 is set to ''global_references(true);echo"var2 is set to '$var2'\n";// var2 is set to 'Example variable'?>global $var;当成是$var =& $GLOBALS['var'];的简写。从而将其它引用赋给$var只改变了本地变量的引用。

如果在foreach语句中给一个具有引用的变量赋值,被引用的对象也被改变。

<?php

$ref=0;

$row=&$ref;

foreach (array(1,2,3) as$row) {// do something}

echo$ref;// 3 - last element of the iterated array

?>

引用做的第二件事是用引用传递变量。这是通过在函数内建立一个本地变量并且该变量在呼叫范围内引用了同一个内容来实现的。例如:

<?phpfunctionfoo(&$var){ $var++;}$a=5;foo($a);?>将使$a变成 6。这是因为在foo函数中变量$var指向了和$a指向的同一个内容。更多详细解释见引用传递。引用做的第三件事是引用返回。引用不是指针。

可以将一个变量通过引用传递给函数,这样该函数就可以修改其参数的值。

<?phpfunctionfoo(&$var){$var++;}$a=5;foo($a);// $a is 6 here?>注意在函数调用时没有引用符号——只有函数定义中有。光是函数定义就足够使参数通过引用来正确传递了

以下内容可以通过引用传递:

变量,例如foo($a);New 语句,例如foo(new foobar());从函数中返回的引用

任何其它表达式都不能通过引用传递,结果未定义。

<?phpfunctionbar(){// Note the missing &$a=5;return$a;}foo(bar());// 自 PHP 5.0.5 起导致致命错误foo($a=5)// 表达式,不是变量foo(5)// 导致致命错误?>

引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!要返回引用,使用此语法:

<?phpclassfoo{ public$value=42; public function &getValue() { return$this->value; }}$obj= newfoo;$myValue= &$obj->getValue();// $myValue is a reference to $obj->value, which is 42.$obj->value=2;echo$myValue;// prints the new value of $obj->value, i.e. 2.?>本例中getValue函数所返回的对象的属性将被赋值,而不是拷贝,就和没有用引用语法一样。和参数传递不同,这里必须在两个地方都用&符号——指出返回的是一个引用,而不是通常的一个拷贝,同样也指出$myValue是作为引用的绑定,而不是通常的赋值。当 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。<?php$a=1;$b=&$a;unset($a);?>不会 unset$b,只是$a。引用定位:global引用:当用global $var声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的:<?php$var=&$GLOBALS["var"]; //这意味着,例如,unset$var