tnatsume00
@tnatsume00 (夏目 崇)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

メソッドチェーンについて

解決したいこと

https://codelikes.com/php-method-chain/
を参考にメソッドチェーンでPHPのコードを書いていたのですが、
Call to a member function getSpaceString()
が発生しました。解決法をご教授ください

発生している問題・エラー

<?php
// Main.php
// Your code here!
    require_once('Calculate.php');
    class Main{
        
        private static $instance;
        public static function getInstance()
        {
            if (!self::$instance) {
                self::$instance = new self();
            }
            return self::$instance;
        }
        
        public function do()
        {

            try{
                echo Calculate::getInstance()
                    ->setType('+')
                    ->setInt1(10)
                    ->setInt2(20)
                    ->getInt1()
                    ->getSpaceString()
                    ->getType()
                    ->getSpaceString()
                    ->getInt2()
                    ->getSpaceString()
                    ->getEqualString()
                    ->getSpaceString()
                    ->execute()
                    ->getResultValue()
                    .PHP_EOL;

                echo Calculate::getInstance()
                    ->setType('-')
                    ->setInt1(10)
                    ->setInt2(51)
                    ->execute()
                    ->getResultValue()
                    .PHP_EOL;

                echo Calculate::getInstance()
                    ->setType('*')
                    ->setInt1(10)
                    ->setInt2(0)
                    ->execute()
                    ->getResultValue()
                    .PHP_EOL;

                echo Calculate::getInstance()
                    ->setType('/')
                    ->setInt1(10)
                    ->setInt2(2)
                    ->execute()
                    ->getResultValue()
                    .PHP_EOL;

                echo Calculate::getInstance()
                    ->setType('/')
                    ->setInt1(10)
                    ->setInt2(0)
                    ->execute()
                    ->getResultValue()
                    .PHP_EOL;

            } catch(Exception $e){
                echo $e->getMessage();
            }
        }
    }
    
    Main::getInstance()
    ->do();
    
?>

<?php
// Calculate.phpphp
class Calculate
{

    private static $instance;

    protected int    $int1;
    protected int    $int2;
    protected string $type;
    private mixed  $resultValue;

    protected const EQUAL_STRING = '=';
    protected const SPACE_STRING = ' ';

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 
     * @param string $type
     * @return self
     */
    public function setType(string $type): self
    {
        $this->resultValue = 0;
        $this->type = $type;

        return $this;
    }

    /**
     * 
     * @param int $int1
     * @return self
     */
    public function setInt1(int $int1): self
    {
        $this->int1 = $int1;
        return $this;
    }

    /**
     * 
     * @param int $int2
     * @return self
     */
    public function setInt2(int $int2): self
    {
        $this->int2 = $int2;
        return $this;
    }
    /**
     * 
     * @return int $int1
     */
    public function getInt1(): int
    {
        return $this->int1;
    }
    /**
     * 
     * @return int $int2
     */
    public function getInt2(): int
    {
        return $this->int2;
    }

    /**
     * 
     * @return string $type
     */
    public function getType(): string
    {
        return $this->type;
    }
    /**
     * 
     * @return mixed $resultValue
     */
    public function getResultValue(): mixed
    {
        return $this->resultValue;
    }
    /**
     * 
     * @return string
     */
    public function getEqualString(): string
    {
        return self::EQUAL_STRING;
    }
    /**
     * 
     * @return string
     */
    public function getSpaceString(): string
    {
        return self::SPACE_STRING;
    }
    /**
     * 
     * @return self
     */
    public function execute(): self
    {
        switch ($this->type) {
            case '+':
                $this->resultValue = $this->add();
                break;
            case '-':
                $this->resultValue = $this->sub();
                break;

            case '*':
                $this->resultValue = $this->cross();
                break;

            case '/':
                $this->resultValue = $this->div();
                break;
            default:
                throw new Exception('+,-,*,/以外の演算子が入力されました。');
                break;
        }
        return $this;
    }

    /**
     * 
     * @return int
     */
    private function add(): int
    {
        return $this->int1 + $this->int2;
    }

    /**
     * 
     * @return int
     */
    private function sub(): int
    {
        return $this->int1 - $this->int2;
    }

    /**
     * 
     * @return int
     */
    private function cross(): int
    {
        return $this->int1 * $this->int2;
    }

    /**
     * 
     * @return float
     */
    private function div(): float
    {
        if ($this->int2 === 0) {
            throw new Exception('割る数は0以外で入力してください。');
        }
        return $this->int1 / $this->int2;
    }
}

上記コードを実行したところ


Fatal error: Uncaught Error: Call to a member function getSpaceString() on int in C:\xampp\htdocs\calc\main.php:24 Stack trace: #0 C:\xampp\htdocs\calc\main.php(74): Main->do() #1 {main} thrown in C:\xampp\htdocs\calc\main.php on line 24

が出力されました。

自分で試したこと

                echo Calculate::getInstance()
                    ->setType('-')
                    ->setInt1(10)
                    ->setInt2(51)
                    ->execute()
                    ->getResultValue()
                    .PHP_EOL;

では問題なく-41が出力されることを確認しております。

なにとぞよろしくお願いいたします。

0

2Answer

public function do()
{

    try{
        echo Calculate::getInstance()
            ->setType('+')
            ->setInt1(10)
            ->setInt2(20)
            ->getInt1()
            ->getSpaceString()

            ...

do() の一部をコピペしてきました.

getInt1() は int を返しています.
int はプリミティブな値でオブジェクトではありません.
getSpaceString()Calculate::class のメンバですので, int 型に getSpaceString() なんてメソッドは無いと怒られています.

おそらくやりたかったこととしては,

10 + 20 = 30

を出力したかったのかな,と思いますので以下を提案します(想定とズレていたら無視してください)

新しく 式 を出力するメソッドを Calculate::class に実装する

public function getFormulaString(): string
{
    return sprintf("%d %s %d = %d", $this->getInt1(), $this->getType(), $this->getInt2(), $this->execute()->getResultValue());
}

image.png

1Like

Comments

  1. @tnatsume00

    Questioner

    まさにこれをやりたかったです。
    コードを示していただきありがとうございます

echo Calculate::getInstance()
    ->setType('+')
    ->setInt1(10)
    ->setInt2(20)
    ->getInt1()
    ->getSpaceString()
// 中略
    ->execute()
    ->getResultValue()
    .PHP_EOL;

$R0 = Calculate::getInstance();
//var_dump($R0);
$R1 = $R0->setType('+');
//var_dump($R1);
$R2 = $R1->setInt1(10);
//var_dump($R2);
$R3 = $R2->setInt2(20);
//var_dump($R3);
$R4 = $R3->getInt1();
//var_dump($R4);
$R5 = $R4->getSpaceString();
//var_dump($R5);
// 中略
$R6 = $R5->execute();
//var_dump($R6);
$R7 = $R6->getResultValue();
//var_dump($R7);
echo $R7.PHP_EOL;

と等価です。
コメントアウトしているvar_dumpを有効にすれば、何が起きているのか確認しやすいと思います。

1Like

Comments

  1. @tnatsume00

    Questioner

    ご回答ありがとうございます。

    参考にさせていただきます

Your answer might help someone💌