2009-08-20 108 views
-1

考慮下面的PHP代碼片段:在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 

?> 

是否可以調用可用()方法是這樣的(並且仍然僅返回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:這段代碼被截斷了,所以不要指望它只是通過它自己使它變得很有意義。

回答

5

基本上你想一個方法返回一個布爾或基於後續方法調用的結果是否將要發生的對象。如果沒有一些大規模的破解(例如,自己閱讀PHP文件並展望未來),我不認爲這是可能的,並且它不應該是因爲你的對象不應該擔心它們被使用的上下文。

相反,您可以在第一次調用時返回與兩種情況相關的對象,例如, DomainLookupResult,有兩種方法,例如存在()和IsAvailable()。然後你可以這樣做:

$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(); 
+0

+1,這是我雖然,我也考慮返回對象域,如果沒有方法的域名被調用,然後__toString會進入行動,並返回true,否則是該字符串不是一個域,它會簡單地返回假。你認爲這是一個很好的理想嗎? – 2009-08-20 14:01:01

+0

請看看我的編輯。 – 2009-08-20 14:04:43

+0

@eyze:不,我只是測試和對象投向布爾時總是如此,__toString()不叫 – 2009-08-20 14:09:33

1

請看方法鏈。

More information

+7

請看月亮。你能給他一個更清晰的答案嗎? :) – Sampson 2009-08-20 13:48:44

+0

的確,這與這個問題無關。 – 2009-08-20 13:57:09

+0

對不起,我錯過了一些東西,並認爲這是解決方案:) – Marien 2009-08-20 13:58:22

3

如果他們返回一個對象,你只能鏈接方法調用! 這是因爲你只能調用對象的方法。

你的代碼的問題是這些方法返回一個非對象值,無論是true還是false。通過鏈接方法,問題沒有得到任何解決。你應該在適用的地方使用它。像鏈接許多setter,而不是你想要使用方法的getter。

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

所以你看到的第一個資源是布爾真或假,你不能調用一個方法。

編輯 這可能是一個「解決方案」。不是一個好的解決方案,但因爲沒有鏈接就更好了。

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(); 
+0

請注意,我正在使用__get魔術方法。 – 2009-08-20 13:55:38

+0

@eyze:這與問題無關。你可以自己添加你需要的東西。這個班只是爲了展示鏈接,而不是那個。將該域作爲參數添加到構造函數中可能會更好。 – OIS 2009-08-20 13:59:10

+0

+1,這是一個有效的解決方案,但不是我正在尋找的。 – 2009-08-20 14:22:38

0

這是可能的,如果你的函數返回一個對象,你可以調用它的方法,等等(見method chaining)。唯一的限制是 - 據我所知 - 是你不能鏈接來自由new(new Object() - > method1() - > method2())創建的對象的調用。

至於你的例子,我沒有看到使用動態類或方法鏈接的東西。

+0

唯一的問題是,如果之後沒有調用Domain :: Available()方法,我將如何返回true而不是對象? – 2009-08-20 14:10:24