洁涣蔡突镰弘暖栖使图遍献少
新建目录18 新建Query.php类文件和demo1.php
Query.php为空
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); var_dump($db);
执行,pdo连接数据库成功.
当访问不存在的方法报错:
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); $db->table();
执行:
__call当访问一个不存在的动态方法时会自动触发
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 //使用implode()将数组转化为字符串 return "方法名:".$name."参数:".implode(",",$args); } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); echo $db->table('staff');
执行:
跨类(域)调用实现
Query.php
<?php //数据库查询类 class Query { private $pdo=null; private $stmt=null; private $table=""; private $fields=""; private $where=""; private $order=""; //构造器 public function __construct($pdo) { //接收外部传入的pdo对象,赋给本类的pdo $this->pdo=$pdo; } //设置要查询的数据表名称 public function table($table) { echo "我是Query中的table方法"; } }
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 $query=new Query($this->pdo);//传入pdo属性 实例化Query类 //call_user_func_array执行回调函数 //跳转到Query类中的table($name)方法 参数为staff($args) return call_user_func_array([$query,$name],$args); } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); echo $db->table('staff');
实现原理解析:
执行$db->table(‘staff’)时,因为Db中没有table()方法,所以会调用魔术方法__call(),在魔术方法中,会跳转到Query类中的table()方法
执行结果:
非链式调用实现数据查询:
Query.php
<?php //数据库查询类 class Query { private $pdo=null; private $stmt=null; private $table=""; private $fields=""; private $where=""; private $order=""; //构造器 public function __construct($pdo) { //接收外部传入的pdo对象,赋给本类的pdo $this->pdo=$pdo; } //设置要查询的数据表名称 public function table($table) { $this->table=$table; } //设置要查询的数据表字段 public function fields($fields) { $this->fields=$fields; } }
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 $query=new Query($this->pdo);//传入pdo属性 实例化Query类 //call_user_func_array执行回调函数 //跳转到Query类中的table($name)方法 参数为staff($args) return call_user_func_array([$query,$name],$args); } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); echo $db->table('staff'); echo $db->fields('name,sex,age');
没有报错,表明正确:
链式调用实现数据查询
Query.php
<?php //数据库查询类 class Query { private $pdo=null; private $stmt=null; private $table=""; private $fields=""; private $where=""; private $order=""; //构造器 public function __construct($pdo) { //接收外部传入的pdo对象,赋给本类的pdo $this->pdo=$pdo; } //设置要查询的数据表名称 public function table($table) { $this->table=$table; //返回当前对象,用于链式调用 return $this; } //设置要查询的数据表字段 public function fields($fields) { $this->fields=$fields; //返回当前对象,用于链式调用 return $this; } //设置查询条件 public function where($where) { $this->where=$where; //返回当前对象,用于链式调用 return $this; } //返回满足条件的第一条记录 public function find() { //事实上,之前的所有方法都是在给本类的属性赋值 //本方法做的就是拼接sql语句,执行sql语句,返回结果集 $table=$this->table; $fields=$this->fields; $where=$this->where; //拼接sql语句 $sql="select {$fields} from {$table} where {$where} limit 1"; die($sql); } }
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 $query=new Query($this->pdo);//传入pdo属性 实例化Query类 //call_user_func_array执行回调函数 //跳转到Query类中的table($name)方法 参数为staff($args) return call_user_func_array([$query,$name],$args); } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); echo $db->table('staff')->fields('name,sex,salary')->where("age < 20")->find();
拼接sql语句正确,说明逻辑没有问题
完善链式调用的单条语句查询:
Query.php
<?php //数据库查询类 class Query { private $pdo=null; private $stmt=null; private $table=""; private $fields=""; private $where=""; private $order=""; //构造器 public function __construct($pdo) { //接收外部传入的pdo对象,赋给本类的pdo $this->pdo=$pdo; } //设置要查询的数据表名称 public function table($table) { $this->table=$table; //返回当前对象,用于链式调用 return $this; } //设置要查询的数据表字段 public function fields($fields) { $this->fields=$fields; //返回当前对象,用于链式调用 return $this; } //设置查询条件 public function where($where) { $this->where=$where; //返回当前对象,用于链式调用 return $this; } //返回满足条件的第一条记录 public function find() { //事实上,之前的所有方法都是在给本类的属性赋值 //本方法做的就是拼接sql语句,执行sql语句,返回结果集 $table=$this->table; $fields=$this->fields; $where=$this->where; //拼接sql语句 $sql="select {$fields} from {$table} where {$where} limit 1"; //生成预处理对象: $this->stmt=$this->pdo->prepare($sql); //执行sql语句 $this->stmt->execute(); //返回结果集 指定为关联的一唯数组 //只查询一条数据 使用fetch()即可 return $this->stmt->fetch(PDO::FETCH_ASSOC); } }
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 $query=new Query($this->pdo);//传入pdo属性 实例化Query类 //call_user_func_array执行回调函数 //跳转到Query类中的table($name)方法 参数为staff($args) return call_user_func_array([$query,$name],$args); } } //实例化Db $db=new Db('127.0.0.1','root','root','myuser'); $row = $db->table('staff')->fields('name,age,salary')->where("age < 40")->find(); //查看单条执行结果 echo "<pre>"; print_r($row); echo "</pre>";
执行:
__callStatic(),访问静态的方法不存在时,会调用这个魔术方法
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 $query=new Query($this->pdo);//传入pdo属性 实例化Query类 //call_user_func_array执行回调函数 //跳转到Query类中的table($name)方法 参数为staff($args) return call_user_func_array([$query,$name],$args); } public static function __callStatic($name, $arguments) { return "方法名:".$name." 参数:".implode(',',$arguments); } } //使用原生的mysqli $db=mysqli_connect('127.0.0.1','root','root','myuser'); echo Db::select('staff','name,sex');
执行:
跨类调用实现多记录查询__callstatic()
Query.php
<?php //数据库查询类 class Query { private $pdo=null; private $stmt=null; private $table=""; private $fields=""; private $where=""; private $order=""; //构造器 public function __construct($pdo) { //接收外部传入的pdo对象,赋给本类的pdo $this->pdo=$pdo; } //设置要查询的数据表名称 public function table($table) { $this->table=$table; //返回当前对象,用于链式调用 return $this; } //设置要查询的数据表字段 public function fields($fields) { $this->fields=$fields; //返回当前对象,用于链式调用 return $this; } //设置查询条件 public function where($where) { $this->where=$where; //返回当前对象,用于链式调用 return $this; } //返回满足条件的第一条记录 public function find() { //事实上,之前的所有方法都是在给本类的属性赋值 //本方法做的就是拼接sql语句,执行sql语句,返回结果集 $table=$this->table; $fields=$this->fields; $where=$this->where; //拼接sql语句 $sql="select {$fields} from {$table} where {$where} limit 1"; //生成预处理对象: $this->stmt=$this->pdo->prepare($sql); //执行sql语句 $this->stmt->execute(); //返回结果集 指定为关联的一唯数组 //只查询一条数据 使用fetch()即可 return $this->stmt->fetch(PDO::FETCH_ASSOC); } //多条记录查询 //注意 select()必须是静态方法 public static function select($db,$table,$fields,$where,$order) { $sql="select {$fields} from {$table} where {$where} {$order};"; //执行sql语句 $res=mysqli_query($db,$sql); //获取结果集 return mysqli_fetch_all($res);//返回结果集:二维数组 } }
demo1.php
<?php //自动加载类文件 spl_autoload_register(function($className) { require "./class/".$className.".php"; }); class Db { public $pdo=null; public function __construct($host="127.0.0.1",$user="root",$pass="root",$dbname="myuser") { try{ $this->pdo=new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass); }catch (PDOException $e) { echo "Connect Error:".$e->getMessage(); } } public function __call($name, $args) { //$name:方法名 $args(可以取其他名称如arguments等)是数组,即参数,所以下方 $query=new Query($this->pdo);//传入pdo属性 实例化Query类 //call_user_func_array执行回调函数 //跳转到Query类中的table($name)方法 参数为staff($args) return call_user_func_array([$query,$name],$args); } public static function __callStatic($name, $arguments) { //静态调用使用名称即可 //$name:静态方法 $arguments:参数名称 return call_user_func_array(['Query',$name],$arguments); } } //使用原生的mysqli $db=mysqli_connect('127.0.0.1','root','root','myuser'); $table="staff"; $fields="name,age,salary"; $where="age < 40"; $order="order by age desc"; //因为是静态调用,没有使用到__call()方法,即类中的pdo对象并没有赋值 //所以要使用自己传递的数据库连接对象 $rows = Db::select($db,$table,$fields,$where,$order); echo "<pre/>"; print_r($rows);
执行:
廉想恃刷钎熊囤侵僵郴奠浇温