61

静的クラスを使用して静的メソッドを連鎖させることは可能ですか? 次のようなことをしたいとします。

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

. . . 明らかに、$value に 14 という数字を割り当てたいと思います。これは可能ですか?

更新:機能しません(「自己」を返すことはできません-インスタンスではありません!)が、これが私の考えが私を連れて行ったところです:

class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return self;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return self;
    }

    public static function result() {
        return self::$value;
    }
}

それを解決した後、静的関数呼び出しをチェーンしようとするのではなく、単にクラスインスタンスを操作する方が理にかなっていると思います(上記の例を何らかの方法で調整できない限り、可能ではないようです)。

4

17 に答える 17

55

上記のCamiloが提供するソリューションが好きです。基本的には、静的メンバーの値を変更するだけであり、チェーンが必要なため(シンタックスシュガーのみですが)、TestClassをインスタンス化するのがおそらく最善の方法です。 。

クラスのインスタンス化を制限したい場合は、シングルトンパターンをお勧めします。

class TestClass
{   
    public static $currentValue;

    private static $_instance = null;

    private function __construct () { }

    public static function getInstance ()
    {
        if (self::$_instance === null) {
            self::$_instance = new self;
        }

        return self::$_instance;
    }

    public function toValue($value) {
        self::$currentValue = $value;
        return $this;
    }

    public function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return $this;
    }

    public function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return $this;
    }

    public function result() {
        return self::$currentValue;
    }
}

// Example Usage:
$result = TestClass::getInstance ()
    ->toValue(5)
    ->add(3)
    ->subtract(2)
    ->add(8)
    ->result();
于 2008-09-24T04:13:20.663 に答える
51
class oop{
    public static $val;

    public static function add($var){
        static::$val+=$var;
        return new static;
    }

    public static function sub($var){
        static::$val-=$var;
        return new static;
    }

    public static function out(){
        return static::$val;
    }

    public static function init($var){
        static::$val=$var;
        return new static;      
    }
}

echo oop::init(5)->add(2)->out();
于 2012-08-10T18:35:19.553 に答える
32

php5.3 の少しクレイジーなコード...ただの楽しみです。

namespace chaining;
class chain
    {
    static public function one()
        {return get_called_class();}

    static public function two()
        {return get_called_class();}
    }

${${${${chain::one()} = chain::two()}::one()}::two()}::one();
于 2012-07-05T05:50:29.817 に答える
24

php7 では、新しいUniform Variable Syntaxにより、目的の構文を使用できるようになります。

<?php

abstract class TestClass {

    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return __CLASS__;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return __CLASS__;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return __CLASS__;
    }

    public static function result() {
        return self::$currentValue;
    }

}

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();
echo $value;

デモ

于 2015-09-02T02:48:48.683 に答える
11

toValue(x) がオブジェクトを返す場合、次のようにすることができます。

$value = TestClass::toValue(5)->add(3)->substract(2)->add(8);

toValue がオブジェクトの新しいインスタンスを返し、各 next メソッドがそれを変更して、$this のインスタンスを返すとします。

于 2008-09-24T03:47:03.567 に答える
6

これはより正確で、簡単で、読みやすい (コード補完が可能)

class Calculator
{   
    public static $value = 0;

    protected static $onlyInstance;

    protected function __construct () 
    {
        // disable creation of public instances 
    }

    protected static function getself()
    {
        if (static::$onlyInstance === null) 
        {
            static::$onlyInstance = new Calculator;
        }

        return static::$onlyInstance;
    }

    /**
     * add to value
     * @param numeric $num 
     * @return \Calculator
     */
    public static function add($num) 
    {
        static::$value += $num;
        return static::getself();
    }

    /**
     * substruct
     * @param string $num
     * @return \Calculator
     */
    public static function subtract($num) 
    {
        static::$value -= $num;
        return static::getself();
    }

    /**
     * multiple by
     * @param string $num
     * @return \Calculator
     */
    public static function multiple($num) 
    {
        static::$value *= $num;
        return static::getself();
    }

    /**
     * devide by
     * @param string $num
     * @return \Calculator
     */
    public static function devide($num) 
    {
        static::$value /= $num;
        return static::getself();
    }

    public static function result()
    {
        return static::$value;
    }
}

例:

echo Calculator::add(5)
        ->subtract(2)
        ->multiple(2.1)
        ->devide(10)
    ->result();

結果: 0.63

于 2014-09-02T12:23:01.847 に答える
3

First メソッドを常に静的メソッドとして使用し、残りをインスタンス メソッドとして使用できます。

$value = Math::toValue(5)->add(3)->subtract(2)->add(8)->result();

またはさらに良い:

 $value = Math::eval(Math::value(5)->add(3)->subtract(2)->add(8));

class Math {
     public $operation;
     public $operationValue;
     public $args;
     public $allOperations = array();

     public function __construct($aOperation, $aValue, $theArgs)
     {
       $this->operation = $aOperation;
       $this->operationValue = $aValue;
       $this->args = $theArgs;
     }

     public static function eval($math) {
       if(strcasecmp(get_class($math), "Math") == 0){
            $newValue = $math->operationValue;
            foreach ($math->allOperations as $operationKey=>$currentOperation) {
                switch($currentOperation->operation){
                    case "add":
                         $newvalue = $currentOperation->operationValue + $currentOperation->args;
                         break;
                    case "subtract":
                         $newvalue = $currentOperation->operationValue - $currentOperation->args;
                         break;
                }
            }
            return $newValue;
       }
       return null;
     }

     public function add($number){
         $math = new Math("add", null, $number);
         $this->allOperations[count($this->allOperations)] &= $math;
         return $this;
     }

     public function subtract($number){
         $math = new Math("subtract", null, $number);
         $this->allOperations[count($this->allOperations)] &= $math;
         return $this;
     }

     public static function value($number){
         return new Math("value", $number, null);
     }
 }

参考までに..私はこれを頭のてっぺんから書きました(サイトのここにあります)。したがって、実行されない場合がありますが、それがアイデアです。eval に対して再帰的なメソッド呼び出しを行うこともできましたが、こちらの方が簡単かもしれないと思いました。詳しく説明したり、その他のヘルプを提供したい場合はお知らせください。

于 2008-09-24T04:35:37.753 に答える
1

一言で言えば…いいえ。:) 解決演算子 (::) は TetsClass::toValue(5) 部分で機能しますが、その後はすべて構文エラーになります。

名前空間が 5.3 で実装されると、「連鎖」 :: 演算子を持つことができますが、名前空間ツリーをドリルダウンするだけです。このようなことの途中でメソッドを持つことはできません。

于 2008-09-24T03:39:01.837 に答える
0

いいえ、これはうまくいきません。演算子は::クラスに評価を戻す必要があるため、TestClass::toValue(5)評価後、::add(3)メソッドは最後の答えに対してのみ評価できます。

したがってtoValue(5)、整数 5 が返された場合、基本的に呼び出しint(5)::add(3)ていることになりますが、これは明らかにエラーです。

于 2008-09-24T03:40:25.063 に答える
0

次のようにも機能します。

ExampleClass::withBanners()->withoutTranslations()->collection($values)

使用するnew static(self::class);

public static function withoutTranslations(): self
{
    self::$withoutTranslations = true;
    
    return new static(self::class);
}

public static function withBanners(): self
{
    return new static(self::class);
}

public static function collection(values): self
{
    return $values;
}
于 2022-02-18T11:01:42.090 に答える