在没有在PHP中创建实例的情况下创建类?

时间:2017-08-09 11:53:05

标签: php oop

如何在php中编写此代码?

Database::select("podomoro")->table("blog")->get();

Database::table("blog")->select("podomoro")->get();

第二种方法可能会在数据库类之后发生变化。

2 个答案:

答案 0 :(得分:1)

我会将这段代码分成几行:

Database::select("podomoro")
    ->table("blog")
    ->get();

第一行实质上是调用类Database的静态方法。这个静态方法返回一个对象实例(可能是一种SELECT对象)。该对象具有方法table()(可能在许多其他方法中)。

在第二行,您调用第一行返回的对象的table()方法。此方法执行某些操作并返回另一个对象实例。当你可以创建方法调用链时,这用于'流畅'接口。

第三行对从第二行调用的函数返回的对象调用方法get()

最简单的实现方式是:

<?php

class Database
{
    public static function select($something)
    {
        // Do something meaningfull
        return new Query();
    }
}

class Query
{
    public function table($name)
    {
        // Do something meaningfull
        return $this;
    }

    public function get()
    {
        // Do something meaningfull

        return $this;
    }
}

,正如其他人在评论中提到的那样,这种模式经常被过度使用 - 实际上 - 经常变成反模式。对于现代框架(如Symfony2等),您应该使用依赖注入和服务实例。

也不鼓励使用流畅的界面。你应该在实现builder模式时使用它们 - 例如。在Doctrine等中QueryBuilder

至于我,如果你不知道,你在做什么,我不建议使用静态类方法。我主要使用它们来重载类构造函数(我创建了私有类构造函数和几个使用不同参数创建类实例的静态方法)。最近我使用它,当将DI集成到没有这些功能的旧框架时 - DI对象本身是一个单独的并且具有静态getInstance()方法。不过,我并不为此感到骄傲。

答案 1 :(得分:0)

我找到了这个问题的答案。 @ tomasz-struczyński的方法也是如此。

    class PhoneNumber
    {
        protected $number;
        protected $countries = [];
        protected $country;
        public function __construct($number)
        {
            $this->number = $number;                
        }

        public static function make($number, $country = [])
        {
            $instance = new static($number);
            return $instance->ofCountry($country);
        }

        public function ofCountry($country)
        {
            $countries = is_array($country) ? $country : func_get_args();
            $instance = clone $this;
            $instance->countries = array_unique(array_merge($instance->countries, $countries));
            return $instance;
        }
    }

    echo "<pre>";
    $dd=PhoneNumber::make(100,"TR")->ofCountry('BE');
    print_r($dd);