mekramy/oop-util

PHP类实用工具。方法链和getter/setter实现

v1.0.0 2020-04-02 07:26 UTC

This package is auto-updated.

Last update: 2024-09-29 05:42:38 UTC


README

定义getter和setter方法

注意:您需要将\MEkramy\OOPUtil\MapGetterSetter特质添加到您的类中

class Person
{
    # Use trait
    use \MEkramy\OOPUtil\MapGetterSetter;

    # class states
    private $fn;
    private $ln;

    # First name getter/setter
    public function setFirstName(string $firstName): void
    {
        $this->fn = $firstName;
    }
    public function getFirstName(): string
    {
        return $this->fn;
    }

    # Last name getter/setter
    public function setLastName(string $lastName): void
    {
        $this->ln = $lastName;
    }
    public function getLastName(): string
    {
        return $this->ln;
    }

    # Full name getter only
    public function getFullName(): string
    {
        return "{$this->fn} {$this->ln}";
    }
}

使用属性

注意:任何属性都将转换为驼峰式风格的getter/setter。因此,您可以以任何喜欢的风格调用属性!

$person = new Person();
# All property access is valid
$person->first_name = 'John';
$person->firstName = 'John';
$person->FirstName = 'John';

$person->lastName = 'Doe';

echo $person->full_name;

# This line throw error because full_name has no setter method
$person->full_name = 'John Doe'; # throws InvalidArgumentException

# This line throw error because no getter/setter defined for notExistsProperty
$person->notExistsProperty = 'Oops!';

处理未定义的getter和setter

您可以处理类的未定义gettersetter

注意:不要使用PHP魔法__get/__set方法。您可以使用实例的__onGetFailed/__onSetFailed方法。

class Person
{
    # class body ...

    private $extra = [];

    # Handle undefined getters
    protected function __onGetFailed($name){
        return array_key_exists($name, $this->extra) ? $this->extra[$name] : null;
    }

    # Handle undefined setters
    protected function __onSetFailed($name, $value): void
    {
        # disallow set full_name
        if(!in_array($name, ['full_name', 'fullName', 'FullName'])){
            $this->extra[$name] = $value;
        }
    }
}

现在您可以使用上面的任何属性

$person = new Person();
$person->birth_date = '1991-1-1';
$person->skills = ['php', 'mysql'];

类方法链调用

定义可链式方法

注意:您需要将\MEkramy\OOPUtil\CanChained特质添加到您的类中

注意:您可以通过重写__canChain/__cantChain方法来定义排除/包含的方法列表以进行链式调用

注意:在这个例子中,__canChain/__cantChain方法都执行相同的工作,您可以只重写其中一个。

class MyClass{

    use \MEkramy\OOPUtil\CanChained;

    /**
     * Methods list to include in chaining call
     *
     * @return array
     */
    protected function __canChain(): array
    {
        return ['doFirst', 'doSecond', 'doThird'];
    }

    /**
     * Methods list to exclude in chaining call
     *
     * @return array
     */
    protected function __cantChain(): array
    {
        return ['getResult'];
    }


    public function doFirst(string $input){ ... }

    public function doSecond(string $input){ ... }

    public function doThird(string $input){ ... }

    public function getResult(): string{ ... }
}

以链式模式使用方法

要调用类的方法链式调用,您需要首先调用chaining方法

$instance = new MyClass();
$instance->chaining()->doFirst('first')->doSecond('second')->doThird('third');

# this line throws error because getResult method not chainable
$instance->chaining()->doFirst('first')->getResult();

获取方法返回值

# A: By calling normally without chaining
$instance->getResult();

# B: By calling getInstance method on chaining call
$instance->chaining()->doFirst('first')->getInstance()->getResult();

使用PHP __call 方法

您可以在类中使用PHP魔法__call方法,并且链式调用仍然可以正常工作!

class Dummy
{
    use \MEkramy\OOPUtil\CanChained;

    protected $calls = [];

    public function __call($name, $arguments)
    {
        $this->calls[] = $name;
    }

    public function __cantChain(){
        return ['print'];
    }

    public function print(){
        print_r($this->calls);
    }
}

$dummy = new Dummy();
$dummy->chaining()->A()->B()->C()->D();
$dummy->print(); // Print: ['A', 'B', 'C', 'D']