Blogger Information
Blog 35
fans 0
comment 0
visits 44107
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP-实例演示属性和方法重载以及用类实现数据库调用--2019年10月8日
Victor的博客
Original
992 people have browsed it

1、实例演示四个属性重载的魔术方法;

2、实例演示call_user_func_array()回调执行函数/对象/类的方法的流程与方式;

3、实例演示方法重载的实现原理与参数获取方式;

4、实例演示数据库连接调用的实现原理与过程(静态方法重载__callStatic实现)

总结:

【1.2.3】集中到一个实例中演示。【4】数据库连接调用在一个实例中演示。 

经过练习发现听得懂看得懂,轮到自己写感觉还是不熟练。总结一下完成过程中发现的问题:

1、使用__unset()自动重载unset()来删除类内成员属性,发现unset后确实访问不到了,但是isset()检查这个属性还是存在,还可以赋值,赋值后又可以正常访问到了。

2、为了避免外部访问重载的魔术方法,我把__set()设为private,结果php会给出警告,建议设为public,这是为什么?

3、对于__call()和__callStatic(),在练习中发现,__call()是可以不管你是静态方法还是实例方法,只要使用$obj->methodname()来调用无权访问或不存在的方法,都自动执行到__call(),在这里随便是private方法还是static方法,都可以在类内转调用,也就是可以实现外部访问类内的私有方法。而__callStatic()则只能针对ClassName::methodname()的自动处理,如果在这里执行类内的常规成员方法,会执行,但要给出一个“非静态声明”的警告。

4没搞明白的是  --->下面这句代码 应该是调用了5次 __callStatic(),那是不是在__callStatic()里,建立了5次连接,实例化了5次 Query?我在代码中做了微调,竟然也成功了。

$staffs = DB::table('staff')

->field('staff_id,name,position,mobile')

->where('staff_id>4')

->limit(6)

->select();

代码如下:

实例 ----  【1.2.3】集中到一个实例中演示
<?php
namespace _1008;

//创建一个画图类,为了练习类常量、静态属性、静态方法以及属性重载和方法重载;

class Draw {

	const DPI = 72; //屏幕分辨率;类常量;
	public static $width = 600; //画布的宽度;静态成员: 用static限定,是类属性
	public static $height = 400; //画布的高度;静态成员: 用static限定,是类属性
	private $pen; //画布的笔 ;私有成员属性;
	private $color; //画笔的颜色;私有成员属性;
	private $bkcolor = '白色'; //画布的背景颜色;私有成员属性;
	protected $scale = 1; //图画的比例;受保护的成员属性;

	//构造函数
	public function __construct($pen, $color) {
		$this->pen = $pen;
		$this->color = $color;
	}

	//设置属性重载:针对访问一个不存在的
	public function __get($property) {
		return isset($property) ? $this->$property : '属性不存在';
	}
	public function __set($property, $value) {
		switch (true) {
		case $property == 'scale':
			$this->$property = (($value > 0) && ($value <= 1)) ? $value : 1;
			break;
		case $property == 'pen':
			$this->$property = (is_string($value) ? $value : '铅笔');
			break;
		case $property == 'color':
			$this->$property = (is_string($value) ? $value : '黑色');
			break;
		case $property == 'bkcolor':
			$this->$property = (is_string($value) ? $value : '白色');
			break;
		default:
			if (isset($property)) {
				$this->$property = $value;
			}

			break;
		}
	}
	public function __isset($property) {
		$has = isset($property) ? true : false;
		return ($property == 'scale') ? false : $has;
		// return ($property == 'scale') ? false : (isset($property) ? true : false);
	}
	public function __unset($property) {
		if ($property == 'bkcolor') {
			unset($this->$property);
			echo '成功删除 ' . $property . '属性', '<br>';
		} else {
			echo '不允许删除' . $property . '属性', '<br>';
		}

		return;
	}

	//设置一个静态方法来重置静态属性
	//静态方法中不允许调用实例属性,但实例方法中可以使用静态属性。

	public static function resetCanvas($newWidth, $newHeight) {
		self::$width = $newWidth;
		self::$height = $newHeight;

	}

	//设置一个私有的成员方法
	private function drawLine() {
		return '画一条直线';
	}
	private static function drawRect() {
		return '画一个矩形';
	}

	//设置__call()方法重载,访问不存在或无权访问的成员方法时自动执行;
	public function __call($method, $params) {
		if (method_exists(self::class, $method)) {
			return call_user_func_array([(self::class), $method], $params);
		}

		return '实例方法调用:' . $method . ' 不存在!<br>参数:<pre>' . print_r($params, true) . '</pre>';
		// return method_exists(self,$method)?'yes':'no';
	}

	//设置__callStatic()方法重载,访问不存在或无权访问的静态方法时自动执行;
	public static function __callStatic($method, $params) {
		if (method_exists(self::class, $method)) {
			return call_user_func_array([(self::class), $method], $params);
		}
		return '静态方法调用:' . $method . ' 不存在!<br>参数:<pre>' . print_r($params, true) . '</pre>';
	}

}

//---------------客户端测试----属性重载-----------------//

echo '类常量 DPI: ' . Draw::DPI, '<br>';
echo '画布宽度: ' . Draw::$width, '  画布高度: ' . Draw::$height, '<br>';
echo '利用静态方法重设画布尺寸', '<br>';
Draw::resetCanvas(800, 600);
echo '画布宽度: ' . Draw::$width, '  画布高度: ' . Draw::$height, '<br>';
echo '类常量和类静态属性方法,不需要实例化即可使用执行';
echo '<hr>';
$draw = new Draw('细毛笔', '黑色');
echo $draw->pen, '<br>';
echo $draw->color = '红色', '<br>';
echo isset($draw->scale) ? '有scale属性' : '无scale属性', '<br>';
echo isset($draw->bkcolor) ? '有bkcolor属性' : '无bkcolor属性', '<br>';
echo '<hr>';
echo $draw->bkcolor, '<br>';
unset($draw->bkcolor);
// echo $draw->bkcolor = '红色', '<br>';
echo $draw->bkcolor, '<br>';
// echo isset($draw->bkcolor) ? '有bkcolor属性' : '无bkcolor属性', '<br>';
echo '<hr>';
unset($draw->pen);
echo isset($draw->pen) ? '有pen属性' : '无pen属性', '<br>';
echo '<hr>';

//---------------客户端测试----方法重载-----------------//

echo '方法重载测试:', '<br>';
echo $draw->drawLine(0, 10, 100, 10);
echo '<hr>';
echo $draw->drawRect(0, 10, 100, 10);
echo '<hr>';
echo $draw->drawCircle(10, 10, 50);
// echo $draw::drawLine(0, 10, 100, 10);
// echo '<hr>';
echo $draw::drawRect(0, 10, 100, 10);
echo '<hr>';
echo $draw::drawCircle(10, 10, 50);

?>
运行实例 »
点击 "运行实例" 按钮查看在线实例

运行效果为:

1008.jpg

实例  ---   【4】数据库连接调用在一个实例中演示
<?php
namespace _1008;

class Query {
	public $pdo = null;
	public $table;
	public $field = '*';
	public $where;
	public $limit;

	public function __construct($pdo) {
		$this->pdo = $pdo;
	}

	public function table($tableName) {
		$this->table = $tableName;
		return $this;
	}
	public function field($fields = '*') {
		$this->field = empty($fields) ? '*' : $fields;
		return $this;
	}
	public function where($where = '') {
		$this->where = empty($where) ? $where : ' WHERE ' . $where;
		return $this;
	}
	public function limit($limit) {
		$this->limit = empty($limit) ? $limit : ' LIMIT ' . $limit;
		return $this;
	}
	public function select() {
		$sql = 'SELECT '
		. $this->field
		. ' FROM '
		. $this->table
		. $this->where
		. $this->limit;

		$stmt = $this->pdo->prepare($sql);
		$stmt->execute();

		return $stmt->fetchAll(\PDO::FETCH_ASSOC);
	}

}

//-------------以下合并写DB class---------------//

class DB {
	protected static $pdo = null;
	protected static $query = null;

	public static function connection() {
		try {
			self::$pdo = new \PDO('mysql:host=127.0.0.1;dbname=test', '******', '********');
		} catch (PDOException $e) {
			die('连接数据库 失败:' . $e->getMessage());
		}
		self::$query = new Query(self::$pdo);
	}
	public static function __callStatic($name, $argus) {
		return call_user_func_array([self::$query, $name], $argus);
	}

}

DB::connection();
$staffs = DB::table('staff')
	->field('staff_id,name,position,mobile')
	->where('staff_id>4')
	->limit(6)
	->select();
foreach ($staffs as $value) {
	print_r($value);
	echo '<br>';

}

?>

运行实例 »
点击 "运行实例" 按钮查看在线实例

10082.jpg














Correction status:qualified

Teacher's comments:你的案例很有意思
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post