Search code examples
phpapiclassmethodschaining

Method chaining a get function to return specific $this properties


I want to be able to use an object like below, to retrieve new orders and new invoices. I feel like it is most readable, but I am having trouble writing the PHP class to work this way.

$amazon = new Amazon();
$amazon->orders('New')->get();
$amazon->invoices('New')->get();

In my PHP class, how would my get() method be able to distinguish whether to return orders or invoices?

<?php

namespace App\Vendors;

class Amazon
{
    private $api_key;
    public $orders;
    public $invoices;

    public function __construct()
    {
        $this->api_key = config('api.key.amazon');
    }

    public function orders($status = null)
    {
        $this->orders = 'orders123';

        return $this;
    }

    public function invoices($status = null)
    {
        $this->invoices = 'invoices123';

        return $this;
    }

    public function get()
    {
        // what is the best way to return order or invoice property
        // when method is chained?
    }

}

Solution

  • A couple of ways, if you want it dynamic and don't do any logic in the methods, use something like __call

    <?php
    class Amazon {
        public $type;
        public $method;
    
        public function get()
        {
            // do logic
            // ...
    
            return 'Fetching: '.$this->method.' ['.$this->type.']';
        }
    
        public function __call($method, $type)
        {
            $this->method = $method;
            $this->type = $type[0];
    
            return $this;
        }
    
    }
    
    $amazon = new Amazon();
    
    echo $amazon->orders('New')->get();
    echo $amazon->invoices('New')->get();
    

    If you want to do logic in the methods, do something like:

    <?php
    class Amazon {
        public $type;
        public $method;
    
        public function get()
        {
            return 'Fetching: '.$this->method.' ['.$this->type.']';
        }
    
        public function orders($type)
        {
            $this->method = 'orders';
            $this->type = $type;
    
            // do logic
            // ...
    
            return $this;
        }
    
        public function invoices($type)
        {
            $this->method = 'invoices';
            $this->type = $type;
    
            // do logic
            // ...
    
            return $this;
        }
    }
    
    $amazon = new Amazon();
    
    echo $amazon->orders('New')->get();
    echo $amazon->invoices('New')->get();