①PHP自定义错误处理:
class proException extends Exception
{
//根据业务需求,自定义错误方法
/**
* 获取错误信息
* @param int $type 类型 1=json 2=数组
* @return array
*/
public function getErrorInfo($type = 2)
{
$err = [
'code' => $this->getCode(),
'msg' => $this->getMessage(),
'file' => $this->getFile(),
'line' => $this->getLine()
];
if ($type == 1) {
return json_encode($err);
}
return $err;
}
}
自定义处理的
try {
if (200 > 100) {
throw new proException('自定义的异常处理', 1002);
} else {
throw new Exception('系统的异常处理', 1002);
}
} catch (proException $e) {
$info = $e->getErrorInfo();
var_dump($info);
} catch (Exception $e) {
echo $e->getMessage();
}
可以使用 $e->getMessage(); $e->getFile() getline()
② __set __get 使用
__get() 和 __set() 都是用来设置私有成员属性(private)的一种方法
用来设置或获取不可达变量的值,在__set() 或 __get() 方法中可以 调用不同的方法或类型来实现返回或设置不同的值的效果,同时 __set() 和__get()不能为 private 或 static方法(有waring报错)。
class stu{
private $a= 12;
private $b = 0;
public $c;
public $d = 0;
public function __get($name) {
if(isset($this->$name)){
return $this->$name;
}
return 123;
}
public function __set($name, $value) {
echo "This is set function";
}
}
$s = new stu();
var_dump($s->a); //output: 12
var_dump($s->b); //output: 0
var_dump($s->c); //output: null
var_dump($s->d); //output: 0
var_dump($s->e); //output: 123
③在一个路由指向一个静态方法, 或者一个实例化对象调用一个静态方法,不会主动调用__construct 方法。可以采用,在该静态方法中返回一个 新的对象实例,然后这个对象中会调用__construct 方法:
class User
{
public $id;
public static function Load( $id )
{
return new User( $id );
}
public static function Create( )
{
return new User( null );
}
public function __construct( $id ) {
$this->id = $id;
}
public function getName()
{
echo $this->id;
return "Jack";
}
}
$uo = User::Load( 1 );
echo( $uo->getName()."\n" ); // 1Jack
④PHP 匿名函数 closure
一部分转自PHP闭包
Closure::__construct — 用于禁止实例化的构造函数
Closure::bind — 复制一个闭包,绑定指定的
this对象和类作用域。Closure::bindTo—复制当前闭包对象,绑定指定的
this对象和类作用域。
class A {
public $base = 100;
}
class B {
private $base = 1000;
}
class C {
private static $base = 10000;
}
$f = function () {
return $this->base + 3;
};
$sf = static function() {
return self::$base + 3;
};
//bind(function,object ,newscope ='static') 这个方法是 Closure::bindTo() 的静态版本
//function Closure 需要绑定的匿名函数。
//object 需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。
//newscop 类作用域,用来决定在闭包中 $this 对象的 私有、保护方法 的可见性
$a = Closure::bind($f, new A);
print_r($a());
echo PHP_EOL;
$b = Closure::bind($f, new B , 'B');
print_r($b());
echo PHP_EOL;
//bindTo
$c = $sf->bindTo(null, 'C');
print_r($c());
echo PHP_EOL;
exit;
上面的例子中,f这个匿名函数中莫名奇妙的有个f这个匿名函数中莫名奇妙的有个this,这个this关键词就是说明这个匿名函数是需要绑定在类中的。
绑定之后,就好像A中有这么个函数一样,但是这个函数是public还是private,bind的最后一个参数就说明了这个函数的可调用范围。
/**
* 复制一个闭包,绑定指定的$this对象和类作用域。
*
* @author 疯狂老司机
*/
class Animal {
private static $cat = "cat";
private $dog = "dog";
public $pig = "pig";
}
/*
* 获取Animal类静态私有成员属性
*/
$cat = static function() {
return Animal::$cat;
};
/*
* 获取Animal实例私有成员属性
*/
$dog = function() {
return $this->dog;
};
/*
* 获取Animal实例公有成员属性
*/
$pig = function() {
return $this->pig;
};
$bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象
$bindDog = Closure::bind($dog, new Animal(), 'Animal');// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包
$bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域
echo $bindCat(),'<br>';// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性
echo $bindDog(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性
echo $bindPig(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性
例子二:
index.php
<?php
function __autoload($class) {
require_once "$class.php";
}
$template = new Template;
$template->render(new Article, 'tpl.php');
?>
Template.php 模板类
<?php
/**
* 模板类,用于渲染输出
*
* @author 疯狂老司机
*/
class Template{
/**
* 渲染方法
*
* @access public
* @param obj 信息类
* @param string 模板文件名
*/
public function render($context, $tpl){
$closure = function($tpl){
ob_start();
include $tpl;
return ob_end_flush();
};
$closure = $closure->bindTo($context, $context); //此处只是绑定闭包
$closure($tpl); //此处才是执行这个闭包方法
}
}
Article.php 信息类
<?php
/**
* 文章信息类
*
* @author 疯狂老司机
*/
class Article{
private $title = "这是文章标题";
private $content = "这是文章内容";
}
tpl.php 模板文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
</head>
<body>
<h1><?php echo $this->title;?></h1>
<p><?php echo $this->content;?></p>
</body>
</html>
运行index.php 同时确保以上文件位于同级目录。
输出:
这是文章标题
这是文章内容
基础
- 子类调用父类的方法可以用 this 也可以是parent this表示一个指针指向当前类,parent表示指向父类
- Trait 代表代码片段,在代码片段中使用 __construct 不会起作用!