2010-09-03 5 views
4

Je ne suis pas sûr si le terme "Wildcard" peut expliquer mon point, mais parfois dans certains scripts prêts, nous sommes en mesure d'appeler une fonction non définie comme find_by_age(23) où l'âge peut être tout ce qui est mappé à une base de données enregistrement de table. Donc, je peux appeler find_by_name, find_by_email, find_by_id et ainsi de suite. Alors, comment pouvons-nous faire une telle chose soit de manière procédurale ou orientée objet?Caractères génériques dans les fonctions PHP

+0

double possible (http://stackoverflow.com/questions/3456763/magic-functions-call-for-functions) – Artefacto

+0

TIP [fonctions magiques __call() pour les fonctions?]: Vous devez indexer les champs vous recherchez la table avec. Plus la table est grande (nombre de champs, tailles variables (varchar) et types de blob, nombre de lignes) plus la recherche sur une rangée de tables est longue. – OIS

Répondre

5

Le terme que vous recherchez est méthode magique.

Fondamentalement comme ceci:

class Foo { 
    public function __call($method,$args) { 
     echo "You were looking for the method $method.\n"; 
    } 
} 

$foo = new Foo(); 
$foo->bar(); // prints "You were looking for the method bar." 

Pour ce que vous cherchez, vous filtrez simplement des appels mauvais de fonction et de réacheminer bons:

class Model { 
    public function find_by_field_name($field,$value) { ... } 
    public function __call($method,$args) { 
     if (substr($method,0,8) === 'find_by_') { 
      $fn = array($this,'find_by_field_name'); 
      $arguments = array_merge(array(substr($method,8)),$args); 
      return call_user_func_array($fn,$arguments); 
     } else { 
      throw new Exception("Method not found"); 
     } 
    } 
} 
+0

Pourquoi 'new Foo() -> bar() 'n'est pas autorisé? –

+0

'new Foo() -> bar()' entraîne une erreur de syntaxe: "unexpected" -> '(T_OBJECT_OPERATOR) ". Cela est vrai à la fois pour PHP 5.3 et PHP 5.4. Je ne l'ai pas encore essayé en PHP 5.5. –

+0

Je viens de confirmer qu'il s'agit toujours d'une erreur de syntaxe dans PHP 5.5, mais ils ont corrigé le déréférencement string/array (comme 'foo() [3]' ou ''xyz '[1]'), ce qui est un problème similaire. –

1

Vous pouvez les utiliser en définissant une méthode magique __call dans votre classe, vous ne pouvez les utiliser que dans les classes. sur la portée mondiale

Je cite PHP Manual:

<?php 
class MethodTest { 
    public function __call($name, $arguments) { 
     // Note: value of $name is case sensitive. 
     echo "Calling object method '$name' " 
      . implode(', ', $arguments). "\n"; 
    } 

    /** As of PHP 5.3.0 */ 
    public static function __callStatic($name, $arguments) { 
     // Note: value of $name is case sensitive. 
     echo "Calling static method '$name' " 
      . implode(', ', $arguments). "\n"; 
    } 
} 

$obj = new MethodTest; 
$obj->runTest('in object context'); 

MethodTest::runTest('in static context'); // As of PHP 5.3.0 
?> 

L'exemple ci-dessus sortie:

Calling object method 'runTest' in object context 
Calling static method 'runTest' in static context 
0

Pour une solution de procédure, vous pouvez utiliser simplement la chaîne concaténation pour faire le travail. Vous pouvez également imaginer un peu les choses en l'appelant une implémentation du strategy pattern.

<?php 

/** 
* Employ a find by name strategy 
*/ 
function find_by_name($name) 
{ 
    echo "You are searching for users with the name $name"; 
    return array(); 
} 

/** 
* Employ a find by age strategy 
*/ 
function find_by_age($age) 
{ 
    echo "You are searching for users who are $age years old"; 
    return array(); 
} 

/** 
* Find users by using a particular strategy 
*/ 
function find_using_strategy($strategy='age', $parameter) 
{ 
    $results = array(); 
    $search_function = 'find_by_' . $search_field; 
    if (function_exists($search_function)) { 
     $results = $search_function($parameter); 
    } 

    return $results; 
} 


$users = find_using_strategy('name', 'Matthew Purdon'); 
var_dump($users); 
Questions connexes