2014-11-17 14 views
7

In hint tipo php-s, non posso usare tipi scalari, come intero o stringa. Quindi questo non è valido:Utilizzare classi wrapper come in JAVA, quando si digita il suggerimento

function myFunc(int $num) { 
    //... 
} 

È possibile utilizzare classi wrapper, come in JAVA? Integer, String, Boolean, ecc ...

Vorrei usare in questo modo:

function myFunc(Integer $num) { 
    //... 
} 

myFunc(5);  // ok 
myFunc("foo"); // error 

lo so, non ci sono classi wrapper in php per impostazione predefinita. Ma com'è possibile, scriverne uno?

+0

È possibile, come ad esempio all'interno di un'is_integer uso funzione di test o is_numeric o is_string, ecc ... –

+0

soluzioni Sì, è possibile, ci sono per questo in utente contribuito sezione del manuale : http://php.net/manual/en/language.oop5.typehinting.php Ma dubito che sia una buona idea. Farà confusione con altri sviluppatori e probabilmente rallenterà. Se si desidera una lingua tipizzata in modo statico, utilizzare uno (come java o Hack di Facebook) – Steve

risposta

5

Dal PHP 5, PHP permette type hinting utilizzando classi (costringendo parametro una funzione/del metodo per essere un'istanza di un classs).

Quindi è possibile creare una classe int che accetta un numero intero PHP nel costruttore (o analizza un numero intero se si consente una stringa contenente un numero intero, come nell'esempio riportato di seguito) e si aspetta nel parametro di una funzione.

Il int classe

<?php 

class int 
{ 

    protected $value; 

    public function __construct($value) 
    { 
     if (!preg_match("/^(0|[-]?[1-9][0-9])*$/", "$value")) 
     { 
     throw new \Exception("{$value} is not a valid integer."); 
     } 
     $this->value = $value; 
    } 

    public function __toString() 
    { 
     return '' . $this->value; 
    } 

} 

Demo

$test = new int(42); 
myFunc($test); 

function myFunc(int $a) { 
    echo "The number is: $a\n"; 
} 

Risultato

KolyMac:test ninsuo$ php types.php 
The number is: 42 
KolyMac:test ninsuo$ 

Ma dovresti fare attenzione agli effetti collaterali.

Il vostro esempio int valuterà a true se lo si usa all'interno di un'espressione (ad esempio, $test + 1), invece di 42 nel nostro caso. È necessario utilizzare l'espressione "$test" + 1 per ottenere 43, poiché lo __toString viene chiamato solo quando si tenta di eseguire il cast dell'oggetto su una stringa.

Nota: non è necessario avvolgere il tipo array, come è possibile digitare in modo nativo sui parametri di funzione/metodo.

Il float classe

<?php 

class float 
{ 

    protected $value; 

    public function __construct($value) 
    { 
     if (!preg_match("/^(0|[-]?[1-9][0-9]*[\.]?[0-9]*)$/", "$value")) 
     { 
     throw new \Exception("{$value} is not a valid floating number."); 
     } 
     $this->value = $value; 
    } 

    public function __toString() 
    { 
     return $this->value; 
    } 

} 

La classe string

<?php 

class string 
{ 

    protected $value; 

    public function __construct($value) 
    { 
     if (is_array($value) || is_resource($value) || (is_object($value) && (!method_exists($value, '__toString')))) 
     { 
     throw new \Exception("{$value} is not a valid string or can't be converted to string."); 
     } 
     $this->value = $value; 
    } 

    public function __toString() 
    { 
     return $this->value; 
    } 

} 

Il bool classe

class bool 
{ 

    protected $value; 

    public function __construct($value) 
    { 
     if (!strcasecmp('true', $value) && !strcasecmp('false', $value) 
      && !in_array($value, array(0, 1, false, true))) 
     { 
     throw new \Exception("{$value} is not a valid boolean."); 
     } 
     $this->value = $value; 
    } 

    public function __toString() 
    { 
     return $this->value; 
    } 

} 

Il object classe

class object 
{ 

    protected $value; 

    public function __construct($value) 
    { 
     if (!is_object($value)) 
     { 
     throw new \Exception("{$value} is not a valid object."); 
     } 
     $this->value = $value; 
    } 

    public function __toString() 
    { 
     return $this->value; // your object itself should implement __tostring` 
    } 

} 
+0

Devo creare ogni int con la nuova parola chiave? Non è possibile, in qualche modo, implementare autoboxing/unboxing? –

+0

No, PHP non supporta quello :( –

+1

No, non è possibile ... Usando questo tipo di classi, questo è come in C, dovresti dichiarare le tue variabili prima di usarle (ad esempio, $ var = new int (42); '), non è del tutto naturale in php :-). –

1

Non esistono classi wrapper per i valori primitivi, n. Immagino che si possa controllare manualmente il tipo:

function myFunc($num) { 
    if(!is_int($num)) { 
     throw new Exception('First parameter must be a number'); 
    } 
    // ... 
} 

Non sarebbe vero il tipo di suggerimento, però.

Il modo migliore sarebbe probabilmente di documentare bene il codice e sperare che venga utilizzato correttamente.

/** 
* @param int $num 
*/ 
function myFunc($num) { 
    // ... 
} 
Problemi correlati