-1

次の PHP スニペットを検討してください。

<?php

class Is
{
    function __get($key)
    {
        $class = __CLASS__ . '_' . $key;

        if (class_exists($class) === true)
        {
            return $this->$key = new $class();
        }

        return false;
    }

    function Domain($string)
    {
        if (preg_match('~^[0-9a-z\-]{1,63}\.[a-z]{2,6}$~i', $string) > 0)
        {
            return true;
        }

        return false;
    }
}

class Is_Domain
{
    function Available($domain)
    {
        if (gethostbynamel($domain) !== false)
        {
            return true;
        }

        return false;
    }
}

$Is = new Is();

var_dump($Is->Domain('google.com')); // true
var_dump($Is->Domain->Available('google.com')); // false

?>

このように Available() メソッドを呼び出すことはできますか (Available メソッドが呼び出されない場合は true または false のみを返します)?

var_dump($Is->Domain('google.com')->Available()); // false

はいの場合、どのように?

編集:これでうまくいきますか?

class Is
{
    function __get($key)
    {
        // same as before
    }

    function Domain($string)
    {
        if (preg_match('~^[0-9a-z\-]{1,63}\.[a-z]{2,6}$~i', $string) > 0)
        {
            return (bool) $this->Domain;
        }

        return false;
    }
}

class Is_Domain
{
    function __toString()
    {
        return true;
    }

    function Available($domain)
    {
        if (gethostbynamel($domain) !== false)
        {
            return true;
        }

        return false;
    }
}

前もって感謝します!

PS : このスニペットは切り詰められているため、それだけで意味を成すとは思わないでください。

4

3 に答える 3

5

基本的に、結果に対する後続のメソッド呼び出しが発生するかどうかに基づいて、メソッドがブール値またはオブジェクトのいずれかを返すようにします。大規模なハック (たとえば、PHP ファイルを自分で読み込んで先を見据える) がなければ、これは可能ではないと思います。

代わりに、Exists() と IsAvailable() などの 2 つのメソッドを持つ DomainLookupResult など、両方のケースに関連するオブジェクトを返す最初の呼び出しを取得できます。次に、次のことができます。

$result = $Is->Domain('google.com');
$isValid = $result->Exists();
$isAvaliable = $result->IsAvailable();

//or chaining:

$isValid = $Is->Domain('google.com')->Exists();
$isAvailable = $Is->Domain('google.com')->IsAvailable();
于 2009-08-20T13:54:16.350 に答える
3

オブジェクトを返す場合にのみ、メソッド呼び出しをチェーンできます! これは、オブジェクトのメソッドしか呼び出せないためです。

コードの問題は、メソッドがオブジェクト以外の値 (true または false) を返すことです。そして、この問題は、メソッドを連鎖させることによって解決されるわけではありません。該当する場合はそれを使用する必要があります。多くのセッターをチェーンするように、本質的に使用したいメソッドがゲッターではありません。

var_dump($Is->Domain->Available('google.com')); // false
//is the same as
$res = $Is->Domain;
$res = $res->Available('google.com'));
var_dump($res);

したがって、最初の res はブール値の true または false であり、そのメソッドを呼び出すことはできません。

編集 これは「解決策」かもしれません。ただし、これは連鎖しないほうがよいため、良い解決策ではありません。

class Domain
{
    public $domain;

    function setDomain($domain) {
        $this->domain = $domain;

        return $this;
    }

    function isDomain($domain = null) {
        if (is_string($domain)) {
            $this->setDomain($domain);
        }
        $result = gethostbynamel($this->domain) !== false;

        return new Result($this, $result);
    }

    function isValid() {
        $result = (bool) preg_match('', $this->domain);
        return new Result($this, $result)
    }
}

class Result
{
    public $result;
    public $object;

    public function __construct($object, $result)
    {
        $this->result = $result;
        $this->object = $object;
    }

    public function __call($method, $arguments)
    {
        if (is_object($this->result)) {
            return call_user_func_array(array($this->result, $method), $arguments);
        }
        if (!$this->result) {
            return $this;
        }
        return call_user_func_array(array($this->object, $method), $arguments);
    }
}

$domain = new Domain();
var_dump($domain->isValid('google.com')->isAvailable()->result);

/編集

これにより、上記の問題が解決されます。

var_dump($Is->Domain('validandfreedomain.com') && $Is_Domain->Available('validandfreedomain.com')); // true

この問題のメソッドを連鎖させたい場合は、このようにすることができます。

class Domain
{
    public $domain;

    function setDomain($domain) {
        $this->domain = $domain;

        return $this;
    }

    function isAvailable() {
        return gethostbynamel($this->domain) !== false;
    }

    function isValid() {
        return (bool) preg_match('', $this->domain);
    }
}

$domain = new Domain();
$result = $domain->setDomain('validandfreedomain.com')->isValid() && $domain->isAvailable();
于 2009-08-20T13:54:26.053 に答える
0

関数がオブジェクトを返す場合、そのメソッドなどを呼び出すことができます (メソッドの連鎖を参照)。唯一の制限は、私の知る限り、 new ( new Object()->method1()->method2() ) によって作成されたオブジェクトからの呼び出しをチェーンできないことです。

あなたの例については、動的クラスまたはメソッドチェーンのものを使用しても意味がありません。

于 2009-08-20T13:57:17.280 に答える