2011-07-13 16 views
10

मेरे पास एक कक्षा द्वारा परिभाषित मेरे वेब ऐप के साथ बातचीत करने के लिए एक एपीआई है। प्रत्येक सार्वजनिक रूप से सुलभ विधि को चलाने से पहले प्रमाणीकरण करने की आवश्यकता होती है। प्रत्येक विधि में एक ही पंक्ति को ऊपर और ऊपर डालने की बजाय, मैं जादू __call फ़ंक्शन का उपयोग करना चाहता हूं। हालांकि, यह केवल निजी या संरक्षित तरीकों पर काम करेगा, और Zend_Json_Server के साथ काम करने के लिए मुझे सार्वजनिक होने की आवश्यकता है।__call सार्वजनिक तरीकों के बराबर

class MY_Api 
{ 
    public function __call($name, $arguments) 
    { 
    //code here that checks arguments for valid auth token and returns an error if false 
    } 

    public function myFunction($param1, $param2, $param3) 
    { 
    //do stuff when the user calls the myFunction and passes the parameters 
    //this function must remain public so that Zend_Json_Server can parse it 
    //but I want it intercepted by a magic method so that the authentication 
    //can be checked and the system bails before it even gets to this function. 
    } 
} 

क्या इन सार्वजनिक कार्यों में शामिल होना संभव है और संभवतः उनके निष्पादन को रद्द करने से पहले रद्द करना संभव है?

+0

क्या आप ज़ेंड एसीएल का उपयोग कर रहे हैं? –

+0

अभी तक नहीं। मुझे यकीन नहीं था कि आवेदन के इस खंड के लिए उपयोग करना उचित था। यह एक बाकी एपीआई है, इसलिए वे लॉग इन नहीं कर रहे हैं और सत्र स्थापित नहीं कर रहे हैं बल्कि एक टोकन पास कर रहे हैं। –

+1

सार्वजनिक विधि को क्या कॉल कर रहा है और क्या वह कॉलर प्रमाणीकरण विधि का आह्वान कर सकता है? – webbiedave

उत्तर

7

__call वास्तव में सार्वजनिक सहित सभी विधियों के लिए काम करता है। हालांकि, सार्वजनिक विधि पहले से मौजूद होने पर यह काम नहीं करेगा, क्योंकि आपकी कक्षा के बाहर कोड पहले से ही सार्वजनिक सदस्यों तक पहुंच सकता है। __call केवल उन सदस्यों के लिए आमंत्रित किया जाता है जो कॉलिंग कोड द्वारा पहुंच योग्य नहीं हैं।

जहाँ तक मुझे पता है कि तुम क्या, के लिए देख रहे करने के लिए वास्तव में कोई विकल्प एक डेकोरेटर पैटर्न के कुछ प्रकार का उपयोग करके छोड़कर देखते हैं: चूंकि आप एक संभव समाधान के रूप में मेरी टिप्पणी के साथ चला गया

class AuthDecorator { 
    private $object; 

    public function __construct($object) { 
     $this->object = $object; 
    } 

    public function __call($method, $params) { 
     //Put code for access checking here 

     if($accessOk) { 
      return call_user_func_array(array($this->object, $method), $params); 
     } 
    } 
} 

$api = new MY_Api(); 
$decoratedApi = new AuthDecorator($api); 

//any calls to decoratedApi would get an auth check, and if ok, 
//go to the normal api class' function 
+0

यहां समाधान क्लासिक आस्पेक्ट ओरिएंटेड प्रोग्रामिंग है जो प्रॉक्सी का उपयोग कर रहा है और आपको वही चाहिए जो आपको चाहिए। मैं कहूंगा कि चूंकि '__call()' केवल तभी कॉल किया जाता है जब कोई विधि पहुंच योग्य नहीं होती है और सभी सार्वजनिक विधियां सुलभ होती हैं, '__call() 'को सार्वजनिक तरीकों से काम नहीं करने के लिए माना जा सकता है। तुमने मुझे उत्साहित कर दिया कि वहां एक छेड़छाड़ हो सकती है, लेकिन हां, जो मामला नहीं था। :( –

+0

या नाम के लिए '_' या तो जोड़ने के लिए सभी कार्यों का नाम बदलना। आप विधि' x' कह सकते हैं, जो '__call' के माध्यम से जाएगी, जो तब सार्वजनिक विधि' x_' को कॉल करेगा। अब मैं सोचता हूं यह, एक सजावटी शायद आसान हो सकता है। :) – GolezTrol

+0

@ डेविड हार्केनेस आह, धन्यवाद - पहलुओं को बिल्कुल वही बात थी जो मैं उल्लेख करने जा रहा था लेकिन मैं केवल लक्षणों के बारे में सोच सकता था :) लेकिन हाँ, आप __call के बारे में काफी सही हैं वह परिप्रेक्ष्य। –

3

, मैंने इसे पोस्टरिटी के उत्तर में स्वरूपित किया है:

यदि पहलू उन्मुख या सजावटी समाधान आपके लिए काम नहीं करते हैं, तो आप उस कोड को रखकर अधिक ढांचे-आधारित समाधान का प्रयास कर सकते हैं जो प्रमाणीकरण की जांच करता है आपकी सार्वजनिक विधि के कॉलर या यहां तक ​​कि ऊपर भी।

+1

मैंने पहले 'Zend_Json_Server' का उपयोग नहीं किया है, लेकिन इसके चुंबन चचेरे भाई' Zend_Controller_Action' 'पूर्वडिस्च()' को परिभाषित करता है जिसे वास्तविक क्रिया विधि से पहले कहा जाता है। शायद JSON घटक ऐसी सुविधा प्रदान करता है। –

+0

अच्छा विचार, @ डेविड, लेकिन Zend_Json_Server नहीं करता है और यह Zend_Server_Abstract को बढ़ाता है, जो या तो नहीं करता है। –

+0

इसे उत्तर देने के लिए धन्यवाद @webbiedave। इसने वास्तव में इस विशेष मामले के लिए समस्या को हल करने का अंत किया। –

संबंधित मुद्दे