0

I have this example class

Class RealUrlConfig
{
    private $domains = [];

    public function addDomain($host, $root_id)
    {
        $this->domains[] = [
            'host' => $host,
            'rootpage_id' => $root_id,
        ];

        return $this; // <-- I added this
    }

    public function removeDomain($host)
    {
        foreach ($this->domains as $key => $item) {
            if ($item['host'] == $host) {
                unset($this->domains[$key]);
            }
        }
    }

    public function getDomains()
    {
        return $this->domains;
    }

    /**
     * TODO: I need this
     */
    public function addAlias($alias)
    {
        $last_modify = array_pop($this->domains);
        $last_modify['alias'] = $alias;

        $this->domains[] = $last_modify;
        return $this;
    }
}

Now I'm trying to create an option to add aliases to the hosts. I could just provide the original host name and the aliases and add that to the array, but I'm trying to do this without the original host - as nested method, so that I can execute it like this:

$url_config = new RealUrlConfig;

$url_config->addDomain('example.com', 1);
$url_config->addDomain('example2.com', 2)->addAlias('www.example2.com');

I added the return $this to addDomain method, so that it returns the object, but I fail to understand, how do I know which array to modify, since I get the whole object.

I could, of course, just read the last added domain from the domains array and modify that, but I', not quite sure if that's the right way.

3
  • just for understanding, why not have a class domain(with host, rootpage_id, and aliases) and then on this class in the addDomain make a new domain and return the newly created domain instead of the RealUrlConfig ? Commented Dec 29, 2016 at 15:53
  • @DoktorOSwaldo On returning the array, I can't modify as part of the object anymore, can it? Commented Dec 29, 2016 at 15:55
  • The answer of bcmcfc is exactly what i recommend. If you return the array instead you can modify the returned array, just return it as a reference. But an array does not have the function addAlias. Commented Dec 29, 2016 at 15:58

1 Answer 1

2

You'd need a class that represents the domain and has an addAlias method on it. Then you'd return that instead of $this.

The alias is a property of the domain, so logically it would make sense to model it in that way.

class Domain 
{
    // constructor not shown for brevity

    public function addAlias($alias)
    {
        $this->alias = $alias;
    }    
}

and in your original class:

public function addDomain($host, $root_id)
{
    $domain = new Domain($host, $root_id);

    // optionally index the domains by the host, so they're easier to access later
    $this->domains[$host] = $domain;
    //$this->domains[] = $domain;

    return $domain;
}

If you did want to index them by host as in the example above, you could simplify it a little:

$this->domains[$host] = new Domain($host, $root_id);
return $this->domains[$host];

Resulting in the option for:

$url_config->addDomain('example2.com', 2)->addAlias('www.example2.com');

Ideally, the config class wouldn't be responsible for the construction of the new Domain objects, as this violates the Single Responsibility Principle. Instead, you'd inject a DomainFactory object into it, which has a newDomain method.

Then you have:

$this->domans[$host] = $this->domainFactory->newDomain($host, $root_id);

in the addDomain method.

I've separated this from the rest of the answer as dependency injection is a somewhat more advanced topic.

Sign up to request clarification or add additional context in comments.

2 Comments

But how do I pass the alias in the last method?
This allows you to pass it the exact way you wanted from your question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.