Error and Exception.php


<?php

//=============================错误处理==============================
//-------------------------------------------------------------------
	/**
	错误处理
	
		1.语法错误
		
		2.运行时错误
		
		3.逻辑错误
		
	错误报告:
	
		错误 E_ERROR
			致命错误,程序通常会死掉,停止往下执行
		
		警告 E_WARNING
			不会中断程序,但某些功能没有执行成功
		
		注意 E_NOTICE
			可屏蔽,不会影响程序执行
	
	开发时开启错误报告,有利于程序调试,运行阶段关闭所以错误报告
	有利于安全。
	
	*/	
//===================================================================
//--------------------------三种错误形式----------------------------
	/*配置文件php.ini中有关错误设置在约为310行*/
	//开启所有错误报告(353行)
	error_reporting  =  E_ALL
	
	/*
	getType(var);//注意
	Notice: Undefined variable: var in C:\lamp\apache2\htdocs\demo
	.php on line 7
	
	getType();//警告
	Warning: Wrong parameter count for gettype() in C:\lamp\apache2
	\htdocs\demo.php on line 8
	
	getTye();//错误
	Fatal error: Call to undefined function gettype1() in C:\lamp\
	apache2\htdocs\demo.php on line 9
	
	*/
	//---------------------------------------------------------------
	//------------------------错误报告的设置------------------------
	error_reporting = E_ALL		//开启所有的错误报告
	error_reporting = E_ALL & ~E_NOTICE//开启所有错误报告除了注意
	...
	//各种错误模式
	E_ALL          		//输出所有的错误警告信息
	E_ERROR     		//输出脚本运行时的错误
	E_WARNING		//运行时的警告信息
	E_PARSE		//编译时的解析错误
	E_NOTICE		//注意
	E_STRICT		//脚本的错误
	E_CORE_ERROR
	E_CORE_WARNING
	E_COMPILE_ERROR
	E_COMPILE_WARNING
	E_USER_ERROR
	E_USER_WARNING
	E_USER_NOTICE
	//---------------------------------------------------------------
	//---------------------在程序中设置错误报告---------------------
	//屏蔽所有错误
	error_reporting(0);
	
	//设置错误等级,在要执行的文件中加入
	error_reporting(E_ALL & ~E_NOTICE);
	
	//设置配置文件,临时改变配置文件
	//参数:要设置的属性,值
	ini_set("error_reporting",E_ALL);

	//取得配置文件中的属性值
	//参数:要获取的属性
	echo ini_get("upload_max_filesize");
	//---------------------------------------------------------------
	//-----------------在程序中关闭与开启错误报告------------------
	//在配置文件中开启显示错误(372行)
	display_errors  =  On
	
	//在程序中设置
	ini_set("display_errors","Off");
	
	//On,Off | 1,0 开关
	ini_set('display_errors',1);
	
	//----------------------------------------------------------------
	//---------------在配置文件中将错误写到错误日志中---------------
	//开启错误日志
	log_errors  =  On
	
	//限制日志大小(防止灌水攻击占满硬盘)
	log_errors_max_len  =  1024
	
	/*默认错误报告写在web服务器的错误日志里,即apache的错误
	日志里apache2\logs,一般不建议这么做,使用error_log自定
	义错误日志文件。
	
	将错误写入报告的前提条件
		1.指定错误报告	error_reporting(E_ALL & ~E_NOTICE);
		2.关闭错误输出	display_errors  =  Off
		3.开启错误日志	log_errors  =  On
		4.指定日志文件	error_log  =  filename
		
		所有设置均可以用ini_set设置
	*/
	
	//可自定义错误信息,输出在指定的错误日志里
	error_log("This is a error message!");
	//写入到操作系统日志中,指定值为 syslog
	error_log  =  syslog
	
	//---------------------------------------------------------------
	//-------------------操作系统记录日志---------------------------
	//define_syslog_variables();     //5.3.0以上版本不需要执行这一句
	openlog('MyLog',LOG_PID,LOG_USER);
	syslog(LOG_WARNING,iconv('utf-8','gbk','我的错误记录'));
	closelog();
	//---------------------------------------------------------------
	//-------------------在程序中设置错误日志-----------------------
	// 将错误日志输出到指定文件中的4个步骤
	ini_set("error_reporting",E_ALL & ~E_NOTICE);//1.指定错误报告
	ini_set('display_errors',0);        				//2.关闭错误显示
	ini_set('log_errors',1);						//3.开启错误日志
	ini_set('error_log','./log.log');				//4.指定日志文件
	//---------------------------------------------------------------
	//------------------------屏蔽当前行错误------------------------
	@	//屏蔽当前行错误
	//---------------------------------------------------------------
	//-------------------用户指定错误的错误级别---------------------
	//用户自己产生
	trigger_error();
	//指定错误的错误级别
	function connect(){
		$link = @mysql_connect('localhost','root','1234567');
		if(!$link){
			trigger_error('数据库连接失败',E_USER_WARNING);
		}
	}
	//---------------------------------------------------------------
	//--------------------------自己处理错误------------------------
	//调用自定义的错误处理函数
	set_error_handler('myerror');
	
	//自定义错误处理方法
	function myerror($level,$message,$file,$line){
		$str = date('Y-m-d H:i:s')."\r\n";
		$str.= '错误级别:'.$level."\r\n";
		$str.= '错误信息:'.$message."\r\n";
		$str.= '错误文件:'.$file."\r\n";
		$str.= '错误行号:'.$line."\r\n";
		error_log($str,3,'./error.log');
	}
//===========================异常处理机制===========================
//-------------------------------------------------------------------
	/*
	异常处理
		在程序运行过程中发生的意料之外的事
		
	try{
	
	}catch(异常对象){
	
	}*/
	//---------------------------------------------------------------
	//---------------------------------------------------------------
	class ONEException extends Exception{
		public function __toString(){
			return $this->message;
		}
	}
	class TWOException extends Exception{
		public function __toString(){
			return $this->message;
		}
	}
	try{
		//抛哪个执行哪个错误处理
		// throw new ONEexception('error one');
		throw new TWOexception('error one');
	}catch(ONEException $e){
		echo 'one';
	}catch(TWOException $e){
		echo 'two';
	}
	//---------------------------------------------------------------
	//-------------------------异常类的作用-------------------------
	/*如果try中的代码正常执行则不执行catch中的代码,如果try
	中的代码未正常执行则抛出异常对象,括号中的$e即为throw
	new Exception("")抛出的异常,try中的代码一旦抛出异常则
	停止执行try中的代码,再跳转到catch中执行代码,catch中
	的代码主要工作为解决异常。*/
	try{
		echo "one";
		
		$file = fopen("hello.txt","r");
		
		if(!$file)
			throw new Exception("文件打开失败");
			
	}catch(Exception $e){	//此处的Exception为对象的类型,类似java
		
		$e->getMessage()."<br>";
		
		touch("hello.txt");
		
		$file=fopen("hello.txt","r");
		
		echo "two";
	}
	//---------------------------------------------------------------
	//---------------------------内置异常类-------------------------
	
	// 内置的异常处理类结构
	class Exception{
		protected $message = 'Unknown exception';	// 异常信息
		protected $code = 0;						// 用户自定义异常代码
		protected $file;							// 发生异常的文件名
		protected $line;							// 发生异常的代码行号

		function __construct($message = null, $code = 0);

		final function getMessage();		//返回异常信息
		final function getCode();			//返回异常代码
		final function getFile();			//返回发生异常的文件名
		final function getLine();			//返回发生异常的代码行号
		final function getTrace();			// backtrace() 数组
		final function getTraceAsString();	// 已格成化成字符串的 getTrace() 信息

		// 可重载的方法 
		function __toString();				// 可输出的字符串
	}
	//---------------------------------------------------------------
	//-------------------------自定义异常类-------------------------
	/*
	自定义异常类的作用:自己写一个解决当前异常的方法。
	自定义异常类的规则:必须是内置类Exception的子类,Exception类
	中只有构造方法和toString()可以重写。*/
	
	//自定义打开文件异常类
	class openFileException extends Exception{
		function open(){	//	<--	解决异常方法
			touch("hello.txt");
			$file = fopen("hello.txt","r");
		}
	}
	//调用自定义异常类
	try{
		$file = fopen("hello.txt","r");
		
		if(!$file)
			throw new openFileException("文件打开失败");
			
	}catch(openFileException $e){
		
		$e->getMessage()."<br>";
		
		$file = $e->open();	//	<--	解决异常
	}
	//---------------------------------------------------------------
	//-----------------------处理多种异常---------------------------
	//处理各种类型异常
	class oneException extends Exception{
		function one(){
			echo "异常one";
		}
	}
	class twoException extends Exception{
		function two(){
			echo "异常two";
		}
	}
	class threeException extends Exception{
		function three(){
			echo "异常three";
		}
	}
	class elseException extends Exception{
		//不做处理
	}
	//处理异常类
	class MyClass{
		function one($value){
			if(!$value){
				throw new oneException("Exception one");
			}
		}
		function two($value){
			if(!$value){
				throw new twoException("Exception two");
			}
		}
		function three($value){
			if(!$value){
				throw new threeException("Exception three");
			}
		}
		function elseException($value){
			if(!$value){
				throw new elseException("Exception else");
			}
		}
	}
	//处理异常
	try{
		$my = new MyClass();
		$my->one(true);
		$my->two(true);
		$my->three(true);
		$my->elseException(false);
	}catch(oneException $e){
		echo $e->getMessage();
		$e->one();
	}catch(twoException $e){
		echo $e->getMessage();
		$e->two();
	}catch(threeException $e){
		echo $e->getMessage();
		$e->three();
	}catch(Exception $e){	//	<--	用父类接收其他异常
		echo $e->getMessage();
	}
	
//-------------------------------------------------------------------
//===================================================================