2009-09-15 7 views
2

J'écris une méthode "catch all" pour mon contrôleur pour ajax. Il est appelé « ajax »: PAide avec PHP method_exists()

C'est ce qu'il ressemble actuellement

public function ajax($method = null) { 

    if (! $method OR ! request::is_ajax()) { 

     return false; 

    } 


    if (method_exists(array($this, 'searchModel'), $method)) { 
     echo $this->searchModel->$method(); 

    } 

    exit; 



} 

Dans le cas qui n'est pas évident, je veux que le ajax d'abord en liberté sous caution si elle pense que ce n'est pas une requête Ajax , puis, vérifiez mon $this->searchModel pour voir s'il a la méthode qui a été transmise en tant qu'argument de la méthode ajax.

Si elle trouve la méthode, elle doit renvoyer la valeur de retour, puis quitter.

Mon problème est que je ne peux pas obtenir le method_exists() pour trouver la méthode! Je sais que ça existe ... J'ai même codé dur (à des fins de test) des méthodes que je connais pour certains existent.

Ça me rend un peu fou, quelqu'un peut-il me dire ce que je fais de mal?

Merci!

P.S. J'utilise le framework Kohana, mais je ne pense pas que ce soit important.

MISE À JOUR

Pensez-vous exposer mes noms de méthodes internes au JavaScript (à savoir public) pourrait être une préoccupation de sécurité?

Répondre

4

Vous utilisez le premier argument à method_exists() comme s'il prenait en charge un argument de rappel, mais il n'acceptait pas de rappel. Il accepte uniquement une instance d'objet ou un nom de classe (une chaîne) pour tester des méthodes statiques.

Essayez ceci:

if (method_exists($this->searchModel, $method)) { 
    echo $this->searchModel->$method(); 
} 

Re votre deuxième question, oui, je pense que c'est un problème de sécurité. Vous n'avez fait aucune validation que la demande est bien formée. Je n'utiliserais pas la solution "fourre-tout" que vous concevez.

+1

Merci Bill! Si je faisais quelque chose comme ça, penses-tu que ça sécuriserait '$ method = 'ajax_'. $ method' .i.e. Le préfixe 'ajax_' assurera-t-il qu'ils ne peuvent accéder à aucune des autres méthodes de mon modèle? – alex

+0

J'étais en fait plus préoccupé par les requêtes malveillantes qui invoquent les méthodes ajax, plutôt que par les requêtes qui invoquent des méthodes non-ajax. –

+0

Eh bien, ce modèle ne traite que des recherches d'utilisateurs - Il devrait être sûr. – alex

2

Je pense que votre code est censé dire:

if(method_exists($this->searchModel, $method)) 
    echo $this->searchModel->$method(); 

Cependant, il est une mauvaise idée d'exposer toutes les méthodes de votre objet searchModel au monde, vous devez préfixer les méthodes ajax avec 'ajax_' ou quelque chose de similaire, de sorte qu'il est seulement possible d'appeler des méthodes avec ce préfixe:

// given that $method is 'user_login' ... 
$realMethod = 'ajax_' . $method;  
if(method_exists($this->searchModel, $realMethod)) 
    // calls $this->searchModel->ajax_user_login(); 
    echo $this->searchModel->$realMethod(); 
+0

Vous avez lu mon esprit avec la chose de préfixe! Merci pour votre réponse. – alex