2011-01-20 5 views
5

Provenendo da C# Sono abituato a sovraccaricare i miei metodi con parametri tipizzati in modo variabile. Poiché non è possibile fare questo in PHP, spesso mi creo metodi come nell'esempio qui sotto, che accetta una variabile, poi mi controllare il tipo e agire di conseguenza:È possibile consentire a una variabile di funzione PHP di essere una stringa o un array come pattern o anti-pattern?

showLength('one'); 
showLength(array(
    'one', 
    'two', 
    'three' 
)); 

function showLength($stringOrArray) { 
    $arr = array(); 
    if(is_array($stringOrArray)) { 
     $arr = $stringOrArray; 
    } else if(is_string($stringOrArray)) { 
     $arr[] = $stringOrArray; 
    } else { 
     //exception 
    } 
    foreach ($arr as $str) { 
     echo strlen($str).'<br/>'; 
    } 
} 

uscita:

3 
3 
3 
5 
4 

Questo mi dà la stessa funzionalità di C# ma sembra un po 'disordinato, come se ci fosse un modo migliore.

È questo il metodo accettato per eseguire il overloading del metodo in PHP (5.3) oppure esiste un modo migliore?

risposta

9

So che molti framework lo fanno per alcune funzioni in cui ha senso, così come alcune delle funzioni principali di PHP. La differenza tra usi "buoni" e "poveri" è la documentazione (docblock). La documentazione deve indicare che il parametro è di tipo misto e i diversi tipi di variabili accettabili.

Ad esempio:

<?php 
/** 
    * Function used to assign roles to a user 
    * @param int $user_id The user's id 
    * @param mixed $role Either a string name of the role 
    *      or an array with string values 
    * 
    * @return bool on success/failure 
    */ 
function addRole($user_id, $role) { 
    if (!is_array($role)) { 
    $role = array($role); 
    } 

    foreach($role as item) { 
    Model::addRole($item); 
    } 

    return true; 
} 
+0

Sì, CodeIgniter lo fa in molte delle sue funzioni e funziona bene e consente di risparmiare un sacco di codice. Finché è documentato, lo consiglio. Ricorda solo di restituire il tipo atteso. Se ho passato un numero intero a un modello, mi aspetto di restituire un oggetto. Se ho passato un array di interi, mi aspetto una schiera di oggetti (forse indicizzati per ID). – Sid

3

Come hai detto tu, non c'è davvero un metodo di accettare multiple tipo i parametri prima di PHP come C# fa, ma questo non dovrebbe causare problemi, purché si Verificare il tipo di i parametri sono prima di fare qualsiasi cosa con loro.

Molte funzioni PHP native accettano parametri di tipo misto, ad es. str_replace().

3

Non mi piace battere un cavallo morto, ma ancora, io peserò qui.

Non lo considererei un anti-pattern; come sottolinea @Merijn, molte funzioni PHP native accettano parametri di tipo misto. Inoltre, molte circostanze come la tua, richiedono che per la concisione la funzione accetti un elemento, o una collezione, di un dato tipo invece di suddividerlo su due funzioni.

Casting per (array) è un modo rapido e semplice per ottenere questa funzionalità:

function printStuff($stuff) 
{ 
    foreach((array) $stuff as $key => $value) { 
     echo sprintf('%d : %s', $key, $value) . PHP_EOL; 
    } 
} 

printStuff("foo"); 
// 0 : foo 

printStuff(array("foo", "bar", "qux")); 
// 0 : foo 
// 1 : bar 
// 2 : qux 

Uso $foo = (array) $foo; È meglio di $foo = array($foo); come quando $foo è già una matrice, non avvolgere nuovamente.


Riferimento


produce i risultati desiderati con scalari; gli oggetti producono risultati diversi. Gli oggetti cast sull'array enumerano le proprietà, quindi usa la discrezione.

Problemi correlati