Blogger Information
Blog 40
fans 1
comment 0
visits 31972
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
编程: 使用方法重载与call_user_func_array()模拟TP框架的链式查询0904
郭稳重啊的博客
Original
758 people have browsed it

0904作业

作业1:编程: 使用方法重载与call_user_func_array()模拟TP框架的链式查询

实例

<?php
/**
 * 数据库查询类
 */

class Query
{
    // 保存sql语句中的各个组成部分
    // SELECT 字段列表 FROM 表名 WHERE 条件
    private $sql = [];

    // 数据库的连接对象
    private $pdo = null;

    //构造方法: 连接数据库
    public function __construct()
    {
        // 连接数据库并返回pdo对象
        $this->pdo = new PDO('mysql:host=127.0.0.1;dbname=php','root','root');
    }
    // table()获取sql语句的表名
    public function table($table)
    {
        $this->sql['table'] = $table;
        return $this;  //返回当前类实例对象,便于链式调用该对象的其它方法
    }

    // fields()获取sql语句的字段列表
    public function fields($fields)
    {
        $this->sql['fields'] = $fields;
        return $this;
    }

    // where()获取sql语句的查询条件
    public function where($where)
    {
        $this->sql['where'] = $where;
        return $this;
    }

    //执行查询,是一个终级方法
    public function select()
    {
        //拼装SELECT查询语句
        $sql = "SELECT {$this->sql['fields']} FROM {$this->sql['table']} WHERE {$this->sql['where']}";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

}

运行实例 »

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

实例

<?php
/**
 * 方法重载的实战案例: 模拟ThinkPHP5.1中的数据库链式操作
 * 用方法重载实现方法跨类调用
 */
echo '<h3 style="text-align: center">编程1:方法重载的实战案例: 模拟ThinkPHP5.1中的数据库链式操作</h3 style>'.
// Db::table()->fields()->where()->select();
require 'Query.php';
// 数据库操作的入口类
class Db
{
    public static function __callStatic($name, $arguments)
    {
        //call_user_func_array([类名, 方法],[])//执行类中的静态方法static
        //call_user_func_array([对象, 方法],[])//执行对象方法
        return call_user_func_array([(new Query()),$name],$arguments);
    }
}

$result = Db::table('staff')
            ->fields('id,name,age,salary')
            ->where('age> 40 ')
            ->select();
//print_r($result);
// 用表格将查询结果格式化输出
$table = '<table border="1" cellpadding="5" cellspacing="0" width="60%" align="center">';
$table .= '<caption style="font-size: 1.5rem;margin:15px;">员工信息表</caption>';
$table .= '<tr bgcolor="#90ee90"><th>ID</th><th>姓名</th><th>年龄</th><th>工资</th></tr>';

foreach ($result as $staff) {
    $table .= '<tr align="center">';
    $table .= '<td>'.$staff['id'].'</td>';
    $table .= '<td>'.$staff['name'].'</td>';
    $table .= '<td>'.$staff['age'].'</td>';
    $table .= '<td>'.$staff['salary'].'</td>';
    $table .= '</tr>';
}

$table .= '</table>';
$num = '<p style="text-align: center"> 共计:  <span style="color:red">'.count($result).'</span>   条记录</p>';
echo '<h4 style="text-align: center">查询staff表的id,name,age,salary字段条件是 age> 40</h4 style>'.$table, $num;


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

`JWFXFXJ$~894EF7K0}0N`U.png


2. 问答: 后期静态绑定的原理与使用场景分析
(1).后期静态绑定的原理
答:
1.准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”的类名。
  当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分,本题为two);
2.当进行非静态方法调用时,即为该对象所属的类。
  所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用:self::,parent::,static::
  以及 forward_static_call()。可用 get_called_class() 函数来得到被调用的方法所在的类名,
3.static:: 则指出了其范围。该功能从语言内部角度考虑被命名为“后期静态绑定”。
   后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。
  也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。
4.通过官方说明我们知道后期静态绑定的范围是继承范围内,
   也就是我们看到static::A();时想要确定static是谁就从调用这个方法的类的继承链去找。

(2).使用场景分析:
问:若父类one创建一个静态方法A和静态方法B,但你想要用子类two去调用静态方法B,
     本意是想调用子类中已重写的静态方法A,并不想调用父类的方法A,但是在父类却不能正确识别出你的调用者是哪个?
答:
1.子类需要继承父类并将父类中静态方法A进行重写
2.然后需要将父类里面的静态方法B去调用父类的静态方法A,
  父类里面一个方法调用另一个方法时,如果被调用方法是普通方法,则默认使用$this作为调用者;
  如果被调用方法时静态方法,则默认使用类/self::作为调用者。
  这里显然是一个静态方法,所以需要使用self::作为调用者去调用静态方法A
3.后期[运行阶段]进行静态绑定/延迟静态绑定,当我们输出子类two的静态方法B时,但是发现业务逻辑说不当通,
  所以接下来我们需要将self::换成 static::,这里static:: 不再被解析为定义当前方法所在的类,
  而是在实际运行时所计算的,以这样输出的结果业务逻辑就正确了。



















































































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