2009-08-20 16 views
-1

Tenir compte de l'extrait de PHP suivant:Est-ce possible en 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 

?> 

Est-il possible d'appeler la méthode disponible() comme celui-ci (et revenir encore seul vrai ou faux si la méthode disponible est pas appelé)?

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

Si oui, comment?

EDIT: Est-ce que cela ferait l'affaire?

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; 
    } 
} 

Merci à l'avance!

PS: Cet extrait est tronqué, ne vous attendez donc pas à ce qu'il soit très intuitif.

Répondre

5

Essentiellement, vous voulez une méthode pour revenir soit un bool ou un objet basé sur si un appel de méthode ultérieure du résultat va se produire. Je ne pense pas que ce soit possible sans un hack massif (par exemple en lisant le fichier PHP en vous et en regardant vers l'avant), et cela ne devrait pas être parce que vos objets ne devraient pas se soucier du contexte dans lequel ils sont utilisés. A la place, vous pouvez obtenir le premier appel pour renvoyer un objet qui est pertinent dans les deux cas, par ex. DomainLookupResult, qui a deux méthodes, par ex. Exists() et IsAvailable(). Vous pouvez alors faire:

$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, C'est ce que je pensais, je pensais aussi renvoyer le domaine objet et si aucune méthode du domaine n'était appelée alors le __toString entrerait en action et retournerait vrai, sinon la chaîne n'était pas un domaine qu'elle retournerait simplement faux. Pensez-vous que c'est une bonne idée? –

+0

S'il vous plaît jeter un oeil à mon édition. –

+0

@eyze: Non. Je viens de tester et les objets quand transtypés en booléens sont toujours vrais, __toString() n'est pas appelé –

1

Veuillez regarder le chaînage des méthodes.

More information

+7

Veuillez regarder la Lune. Pouvez-vous lui donner une réponse plus claire à la place? :) – Sampson

+0

En effet, ce n'est pas pertinent à cette question. –

+0

Je suis désolé, j'ai raté quelque chose et j'ai pensé que c'était la solution :) – Marien

3

Vous pouvez uniquement chaîner les appels de méthode s'ils renvoient un objet! C'est parce que vous ne pouvez appeler que des méthodes sur des objets.

Le problème avec votre code est que les méthodes retournent une valeur non-objet, vrai ou faux. Et le problème n'est en aucune façon mieux résolu par les méthodes de chaînage. Vous devriez l'utiliser là où c'est applicable. Comme enchaîner de nombreux setters, PAS getters que les méthodes que vous voulez utiliser est essentiellement. Donc, vous voyez que la première res est un booléen vrai ou faux, et vous ne pouvez pas appeler une méthode à ce sujet.

modifier Ceci pourrait être une "solution". Ce n'est pas une bonne solution, car c'est mieux sans enchaîner.

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); 

/modifier

Cela permettra de résoudre votre problème ci-dessus.

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

Si vous souhaitez désespérément enchaîner une méthode pour ce problème, vous pouvez le faire plus comme ceci.

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

Veuillez noter que j'utilise la méthode magique __get. –

+0

@eyze: cela n'a rien à voir avec la question. Vous pouvez ajouter vous-même ce dont vous avez besoin. La classe est juste pour démontrer l'enchaînement, et mal à cela. La tâche serait probablement meilleure avec l'ajout du domaine en tant que param au constructeur. – OIS

+0

+1, c'est une solution valable mais pas celle que je cherche. –

0

Il est possible, si votre fonction retourne un objet, vous pouvez appeler sa méthode, et ainsi de suite (voir method chaining). La seule limitation est - pour autant que je sache - est que vous ne pouvez pas enchaîner les appels d'un objet créé par new (new Object() -> method1() -> method2()). En ce qui concerne votre exemple, je ne vois pas l'intérêt d'utiliser la classe dynamique ou la méthode de chaînage de méthode.

+0

Le seul problème est, comment devrais-je retourner vrai au lieu d'un objet si la méthode Domain :: Available() n'est pas appelée après? –