make class 的 oop 结构,例如 PDO class 结构

oop structure for make class such as PDO class structure

如何制作 class 类似 PDO 或 ORM 的结构

 $query = DB::table('users')->select('name');

 $users = $query->addSelect('age')->get();

 $stmt = $pdo->prepare($sql);
 $stmt->bindvalue(':u',intval($_SESSION['userId']),PDO::PARAM_INT);
 $stmt->execute();

$query 或 $stmt 返回了什么?

如何设计像他们一样的class结构?

谢谢

编辑

 $query = DB::table('users')->select('name');
 meaning : 
 function select(){
  //
  return $this;
 }

此结构的 $query 返回了什么:

 $query->addSelect('age')->get();

PDO 是通过返回一个新的 class (PDOStatement) 和它自己的方法 (read more about it) 来完成的,但它与以下内容相同:

<?php
class ClassOne
{
    private $connection;
    public function __construct($database_stuff)
    {
        $this->connection = $database_stuff;
    }

    public function prepare($sql)
    {
        // Code that does something with the $sql
        // Then return a new class
        return new ClassTwo($this);
    }
}

class ClassTwo
{
    private $ClassOne;

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

    public function execute()
    {
        // Code that does something with ClassOne
    }
}

# Start that initial class
$Class = new ClassOne('database:type;host=example;etc=yadayada');
# Do class one method
$query = $Class->prepare("SELECT * FROM fake_table");
# $query is now ClassTwo, so you do method from ClassTwo
$query->execute();

实现了将方法链接在一起的能力,因为当前方法 returns 对象以 $this:

的形式返回
<?php
    class   DBClass
    {
        protected   $connection,
                    $value;

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

        public  function prepare($value)
        {
            $this->value    =   $value;
            # Return the object
            return $this;
        }

        public  function execute()
        {
            echo $this->value;
            # Return the object
            return $this;
        }
    }

    $con    =   new DBClass("login creds");
    $con->prepare("update stuff if stuff = 'things'")->execute();
?>