博客列表 >PHP-实例演示属性和方法重载以及用类实现数据库调用--2019年10月8日

PHP-实例演示属性和方法重载以及用类实现数据库调用--2019年10月8日

Victor的博客
Victor的博客原创
2019年10月16日 02:16:20991浏览

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














声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议