2013-02-13 30 views
5

मैं एक फ़ाइल को स्कैन करने के लिए सभी परिभाषित कक्षाएं, कुछ भी वे का विस्तार, किसी भी बनाई उदाहरणों, और किसी भी समय वे स्थिर लागू किया गया लगता है tokenizer उपयोग करने के लिए कोशिश कर रहा हूँ।मैं PHP फ़ाइल में उपयोग की जाने वाली सभी कक्षाओं को कैसे ढूंढूं?

<?php 

$tokens = token_get_all(file_get_contents($file)); 

$used_classes = array(); 
$defined_classes = array(); 
$variable_classes = array(); 

foreach($tokens as $i => $token) { 

    if(is_array($token)) { 

     if(isset($tokens[$i - 2][0], $tokens[$i - 1][0])) { 

      // new [class] 
      if ($tokens[$i - 2][0] == T_NEW AND $tokens[$i - 1][0] == T_WHITESPACE) { 

       if($tokens[$i][0] == T_STRING) { 
        $used_classes[$token[1]] = TRUE; 

       // new $variable() 
       } elseif($tokens[$i][0] == T_VARIABLE) {  

        // @todo, this is really broken. However, do best to look for the assignment 
        if(preg_match('~\$var\s*=\s*([\'"])((?:(?!\1).)*)\1~', $text, $match)) { 
         if(empty($extension_classes[$match[2]])) { 
          $used_classes[$match[2]] = TRUE; 
         } 
        } elseif($token[1] !== '$this') { 
         $variable_classes[$token[1]] = TRUE; 
        } 
       } 

      } 

      // class [class] 
      if ($tokens[$i - 2][0] == T_CLASS AND $tokens[$i - 1][0] == T_WHITESPACE) { 

       if($tokens[$i][0] == T_STRING) { 
        $defined_classes[$token[1]] = TRUE; 
       } 
      } 


      // @todo: find more classes \/ 

      // class [classname] extends [class] ??? 
      // [class]::method()??? 
     } 
    } 
} 

ऊपर उल्लिखित PHP कक्षाओं के किसी भी अतिरिक्त उदाहरण को खोजने के लिए मैं इस कोड को कैसे बढ़ा सकता हूं?

+0

PHP में जादू निरंतर __ फ़ाइल __ (बिना रिक्त स्थान के) है। आप इस फ़ाइल को खोल सकते हैं (fopen या file_get_contents) और preg_match (जैसे /^\s*class(.*)$/ और /(.*)::(.*)/ और इसी तरह) के माध्यम से इसे खोज सकते हैं। पता है कि काफी कठोर समाधान नहीं है तो शायद किसी को बेहतर मिलेगा। यदि आप सभी कक्षाएं खोजना चाहते हैं, तो आप फंक्शन get_declared_classes (http://php.net/manual/en/function.get-declared-classes.php) का उपयोग कर सकते हैं और इसलिए, याद रखें, कि कोर क्लासेस भी शामिल किए जाएंगे। – tomis

+0

आपकी तीन सिफारिशों में से केवल रेगेक्स के साथ खोज करने के लिए PHP कोड के स्थिर विश्लेषण के साथ कुछ भी करना है। हालांकि, मैं रेगेक्स से बचने के बजाय PHP पार्सर अधिक विश्वासयोग्य होगा। मैं यह भी कल्पना नहीं कर सकता कि एक परिवर्तनीय चर खोजने के लिए रेगेक्स को कितना जटिल होना होगा। – Xeoncross

+0

खैर, मुझे डर है कि आपको पूरा भरने का अनुरोध (क्लास परिभाषा और लक्ष्य फ़ाइल में कॉल ढूंढना) संभव नहीं है ... – tomis

उत्तर

2

पार्सिंग और फिर PHP कोड की व्याख्या कुछ है कि एक regex का उपयोग कर अच्छी तरह से हल किया जा सकता है। आपको लगता है कि वास्तव में गुंजाइश, वर्ग के नाम, उत्तराधिकार आदि जैसी चीजों को समझ सकते हैं कि आप क्या चाहते करने के लिए सक्षम होने के लिए एक कुछ और अधिक चतुर, एक राज्य मशीन की तरह, की आवश्यकता होगी।

यह सिर्फ इतना होता है कि मैं एक PHP-to-Javascript कनवर्टर एक राज्य मशीन है कि लगभग के सबसे करेंगे के आधार पर लिखा है के लिए हो कि आप क्या करना चाहते हैं:

सभी परिभाषित वर्गों

हां, सभी वर्ग सूचीबद्ध क्लासस्कोप को उनके सभी चर के साथ बनाते हैं और उनकी विधियां फ़ंक्शनस्कोप के रूप में बनाई जाती हैं, ताकि आप बता सकें कि कक्षा में कौन सी विधियां हैं।

कुछ भी वे का विस्तार

हाँ, हर वर्ग उसे अपने जनक ClassScope में सूचीबद्ध वर्गों है है -> $ parentClasses

किसी भी बनाई उदाहरणों

नहीं, लेकिन wouldn ' इन रिकॉर्ड करने के लिए अतिरिक्त कोड जोड़ने के लिए मुश्किल हो।

किसी भी समय उन्हें स्थिर रूप से बुलाया गया था।

नहीं - लेकिन यह है कि वास्तव में एक regex के साथ किया जा सकता है।

हालांकि यह आपकी समस्या को ठीक तरह से हल नहीं करता है, लेकिन जिस परियोजना के रूप में यह खड़ा है, वह आपको 9 5% रास्ता देगा जो आप करना चाहते हैं, जो कुछ हफ्तों के काम को बचाएगा।

0

Inclued, शायद यहाँ में देख लायक है, हालांकि मुझे नहीं लगता कि यह किसी भी डेटा जिसके आगे फ़ाइलें/वर्गों शामिल किया गया और के साथ आप प्रदान करेगा कितनी बार।

+0

यह जानने के लिए एक अच्छा टूल है, लेकिन दुर्भाग्य से यह आवश्यक है कि आप कोड चलाएं। मैं स्थैतिक विश्लेषण की तलाश में हूं क्योंकि एक PHP सिस्टम के हर पहलू को चलाने के लिए यथार्थवादी नहीं है जिसमें यूनिट परीक्षणों से पूर्ण कोड-कवरेज नहीं है। – Xeoncross

0

मुझे नहीं लगता कि आप सिर्फ विश्लेषण करने टोकन करके ऐसा कर सकते हैं।

तुम एक इंटरफ़ेस को लागू करने के लिए कि क्या यह अपने कोड में इस्तेमाल किया गया है किसी भी वर्ग के नाम, क्या वास्तविक परिभाषा यह किसी भी विरासत संबंधों सहित, का प्रतिनिधित्व करता है के लिए, पता करने की जरूरत है, और। वर्ग/इंटरफ़ेस परिभाषा किसी अन्य फ़ाइल में हो सकती है; उस फ़ाइल को कुछ शर्त के तहत शामिल किया जा सकता है। आपके पास एक ही कक्षा का नाम अलग-अलग फ़ाइलों में अलग-अलग परिभाषित हो सकता है। इसलिए सामान्य रूप से आपको उन सभी फ़ाइलों को संसाधित करने की आवश्यकता होती है जिनमें आपके सिस्टम को एक साथ शामिल किया जाता है।

क्या आप एक आधार के रूप जरूरत है एक उपकरण है कि PHP पार्स करके असली प्रतीक टेबल बनाता है। आप उस से अपने परिणाम की गणना करने में सक्षम हो सकते हैं। (इस तरह के एक उपकरण के शुरूआती स्थान के रूप में टोकन का विश्लेषण करती है, लेकिन यह तुच्छ टोकन स्कैनिंग तुलना में कहीं अधिक काम है)।

0

ऐसा लगता है कि आप केवल कोड लोड करते हैं, तो आप प्रत्येक वर्ग की जांच के लिए अंतर्निहित प्रतिबिंब API (ReflectionClass::_construct(), आदि) का उपयोग कर सकते हैं।

कक्षाएं स्वयं प्राप्त करने के लिए, अंतर्निहित get_declared_classes() का उपयोग करें।

(नोट:। मैं इस प्रयास नहीं किया है, तो YMMV)

+0

यह वास्तव में स्वीकार्य नहीं है, हालांकि, शायद मैं एक प्रक्रिया को फोर्क कर सकता हूं और फ़ाइल लोड कर सकता हूं (भले ही यह सब कुछ मिटा देता है) और पाए गए नए कार्यों/वर्गों को वापस कर दें। – Xeoncross