दिलचस्प पोस्ट
किसी वैरिएबल में नामित जावास्क्रिप्ट फंक्शन कॉल करना एकाधिक फ़ाइलों के लिए बैच फ़ाइल खींचें और छोड़ें? चित्रण से जीमेल को छवि कैसे संलग्न करें? __pycache__ क्या है? कैसे उपयोगकर्ता आईपी पता Meteor सर्वर में प्राप्त करने के लिए? एंड्रॉइड: डेटा भेज रहा है> 20 बाइट्स द्वारा BLE बहुत कम पैरामीटर अपेक्षित 1, रिकॉर्डसेट समस्या सुपर () को एक व्युत्पन्न वर्ग में बुलाते समय, क्या मैं स्वयं .__ वर्ग__ में पारित कर सकता हूं? पटरियों, प्रमाणीकरण का आश्वासन, सीएसआरएफ मुद्दे जावास्क्रिप्ट के बिल्टिन स्ट्रिंग्स क्या हैं? एसक्यूएल 2008 में विदेशी कुंजी रिश्ते से स्टेटमेंट हटाएं? डीजेंगो, एक कस्टम 500/404 त्रुटि पृष्ठ बना रहा है एंड्रॉइड: चेकबॉक्स का सेट रंग एंड्रॉइड में फोन कॉल कैसे रिकॉर्ड करें? जावास्क्रिप्ट में एक विलंब रखें

मैं PHP परियोजना में अप्रयुक्त फ़ंक्शन कैसे प्राप्त करूं?

PHP परियोजना में कोई भी अप्रयुक्त फ़ंक्शन कैसे मिल सकता है?

क्या इसमें विशेषताएं या एपीआई PHP में बनी हैं जो मुझे अपना कोडबेस का विश्लेषण करने की इजाजत देगी – उदाहरण के लिए प्रतिबिंब , token_get_all() ?

क्या ये एपीआई पर्याप्त रूप से समृद्ध होती हैं, क्योंकि मुझे इस प्रकार के विश्लेषण के लिए तीसरे पक्ष के उपकरण पर भरोसा नहीं करना चाहिए?

वेब के समाधान से एकत्रित समाधान "मैं PHP परियोजना में अप्रयुक्त फ़ंक्शन कैसे प्राप्त करूं?"

आप सेबस्टियन बर्गमन की मृत कोड डिटेक्टर की कोशिश कर सकते हैं:

phpdcd PHP कोड के लिए एक डेड कोड डिटेक्टर (डीसीडी) है यह सभी घोषित कार्यों और विधियों के लिए एक PHP परियोजना को स्कैन करता है और उन "मृत कोड" के रूप में रिपोर्ट करता है जिन्हें कम से कम एक बार कॉल नहीं किया जाता है

स्रोत: https://github.com/sebastianbergmann/phpdcd

ध्यान दें कि यह एक स्थिर कोड विश्लेषक है, इसलिए यह उन विधियों के लिए झूठी सकारात्मक दे सकता है जिन्हें केवल गतिशील रूप से कहा जाता है, जैसे यह $foo = 'fn'; $foo(); पता नहीं लगा सकता $foo = 'fn'; $foo(); $foo = 'fn'; $foo();

आप इसे पीअर के द्वारा स्थापित कर सकते हैं:

 pear install phpunit/phpdcd-beta 

इसके बाद आप निम्न विकल्पों के साथ उपयोग कर सकते हैं:

 Usage: phpdcd [switches] <directory|file> ... --recursive Report code as dead if it is only called by dead code. --exclude <dir> Exclude <dir> from code analysis. --suffixes <suffix> A comma-separated list of file suffixes to check. --help Prints this usage information. --version Prints the version and exits. --verbose Print progress bar. 

अधिक टूल:


नोट: रिपॉज़िटरी नोटिस के अनुसार, यह परियोजना अब नहीं रखी गई है और इसकी रिपॉजिटरी केवल अभिलेखीय उद्देश्यों के लिए रखी गई है । तो आपका लाभ भिन्न हो सकता है

प्रतिक्रिया के लिए धन्यवाद ग्रेग और डेव मैं जो कुछ भी देख रहा था वह काफी नहीं था, लेकिन मैंने शोध करने में थोड़ा समय लगाया और इस त्वरित और गंदे समाधान के साथ आया:

 <?php $functions = array(); $path = "/path/to/my/php/project"; define_dir($path, $functions); reference_dir($path, $functions); echo "<table>" . "<tr>" . "<th>Name</th>" . "<th>Defined</th>" . "<th>Referenced</th>" . "</tr>"; foreach ($functions as $name => $value) { echo "<tr>" . "<td>" . htmlentities($name) . "</td>" . "<td>" . (isset($value[0]) ? count($value[0]) : "-") . "</td>" . "<td>" . (isset($value[1]) ? count($value[1]) : "-") . "</td>" . "</tr>"; } echo "</table>"; function define_dir($path, &$functions) { if ($dir = opendir($path)) { while (($file = readdir($dir)) !== false) { if (substr($file, 0, 1) == ".") continue; if (is_dir($path . "/" . $file)) { define_dir($path . "/" . $file, $functions); } else { if (substr($file, - 4, 4) != ".php") continue; define_file($path . "/" . $file, $functions); } } } } function define_file($path, &$functions) { $tokens = token_get_all(file_get_contents($path)); for ($i = 0; $i < count($tokens); $i++) { $token = $tokens[$i]; if (is_array($token)) { if ($token[0] != T_FUNCTION) continue; $i++; $token = $tokens[$i]; if ($token[0] != T_WHITESPACE) die("T_WHITESPACE"); $i++; $token = $tokens[$i]; if ($token[0] != T_STRING) die("T_STRING"); $functions[$token[1]][0][] = array($path, $token[2]); } } } function reference_dir($path, &$functions) { if ($dir = opendir($path)) { while (($file = readdir($dir)) !== false) { if (substr($file, 0, 1) == ".") continue; if (is_dir($path . "/" . $file)) { reference_dir($path . "/" . $file, $functions); } else { if (substr($file, - 4, 4) != ".php") continue; reference_file($path . "/" . $file, $functions); } } } } function reference_file($path, &$functions) { $tokens = token_get_all(file_get_contents($path)); for ($i = 0; $i < count($tokens); $i++) { $token = $tokens[$i]; if (is_array($token)) { if ($token[0] != T_STRING) continue; if ($tokens[$i + 1] != "(") continue; $functions[$token[1]][1][] = array($path, $token[2]); } } } ?> 

मैं शायद इस पर कुछ और समय बिताऊंगा ताकि मैं फ़ंक्शन परिभाषाओं और संदर्भों की फाइलों और लाइन संख्याओं को शीघ्रता से ढूंढ सकूं; यह जानकारी एकत्रित की जा रही है, बस प्रदर्शित नहीं है

यह बिट स्क्रिप्टिंग मदद कर सकता है:

 grep -rhio ^function\ .*\( .|awk -F'[( ]' '{print "echo -n " $2 " && grep -rin " $2 " .|grep -v function|wc -l"}'|bash|grep 0 

यह बुनियादी तौर पर फ़ंक्शन परिभाषाओं के लिए वर्तमान निर्देशिका को गड़बड़ कर देता है, हिट को एवीसी से गुजरता है, जो निम्न करने के लिए एक आदेश बनाता है:

  • फ़ंक्शन का नाम मुद्रित करें
  • फिर से इसके लिए फिर से grep
  • फ़ंक्शन परिभाषाओं को फ़िल्टर करने के लिए आउटपुट को grep -v आउटपुट करने के लिए पाइपिंग करना ताकि फ़ंक्शन को कॉल बनाए रखा जा सके
  • इस आउटपुट को wc -l को पाइप जो लाइन गिनती प्रिंट करता है

यह कमांड तब निष्पादन के लिए bash पर भेजा जाता है और आउटपुट को 0 के लिए grepped किया जाता है, जो कि फ़ंक्शन के लिए 0 कॉल को इंगित करेगा।

ध्यान दें कि इससे ऊपर की समस्या को हल नहीं होगा, इसलिए आउटपुट में कुछ गलत सकारात्मक हो सकते हैं।

अगर मुझे सही याद है तो आप phpCellGraph का उपयोग कर सकते हैं। यह आपके लिए सभी तरीकों के साथ एक अच्छा ग्राफ (छवि) उत्पन्न करेगा यदि कोई विधि किसी अन्य से जुड़ी नहीं है, तो यह एक अच्छा संकेत है कि विधि अनाथ है।

यहां एक उदाहरण है: classGallerySystem.png

विधि getKeywordSetOfCategories() अनाथ है।

बस वैसे ही, आपको कोई चित्र नहीं लेना है- phpCallGraph भी एक पाठ फ़ाइल या PHP सरणी उत्पन्न कर सकता है, आदि।

उपयोग: find_unused_functions.php <root_directory>

नोट: यह समस्या के लिए एक 'त्वरित-गंदे' दृष्टिकोण है। यह स्क्रिप्ट केवल फाइलों पर एक लिखेक्स पास करता है, और ऐसे परिस्थितियों का सम्मान नहीं करता है जहां अलग-अलग मॉड्यूल समान रूप से नामित फ़ंक्शंस या विधियों को परिभाषित करते हैं। यदि आप अपने PHP विकास के लिए आईडीई का उपयोग करते हैं, तो यह एक अधिक व्यापक समाधान प्रदान कर सकता है।

PHP 5 की आवश्यकता है

आपको एक कॉपी और पेस्ट बचाने के लिए, एक सीधा डाउनलोड, और कोई नया संस्करण, यहां उपलब्ध है

 #!/usr/bin/php -f <?php // ============================================================================ // // find_unused_functions.php // // Find unused functions in a set of PHP files. // version 1.3 // // ============================================================================ // // Copyright (c) 2011, Andrey Butov. All Rights Reserved. // This script is provided as is, without warranty of any kind. // // http://www.andreybutov.com // // ============================================================================ // This may take a bit of memory... ini_set('memory_limit', '2048M'); if ( !isset($argv[1]) ) { usage(); } $root_dir = $argv[1]; if ( !is_dir($root_dir) || !is_readable($root_dir) ) { echo "ERROR: '$root_dir' is not a readable directory.\n"; usage(); } $files = php_files($root_dir); $tokenized = array(); if ( count($files) == 0 ) { echo "No PHP files found.\n"; exit; } $defined_functions = array(); foreach ( $files as $file ) { $tokens = tokenize($file); if ( $tokens ) { // We retain the tokenized versions of each file, // because we'll be using the tokens later to search // for function 'uses', and we don't want to // re-tokenize the same files again. $tokenized[$file] = $tokens; for ( $i = 0 ; $i < count($tokens) ; ++$i ) { $current_token = $tokens[$i]; $next_token = safe_arr($tokens, $i + 2, false); if ( is_array($current_token) && $next_token && is_array($next_token) ) { if ( safe_arr($current_token, 0) == T_FUNCTION ) { // Find the 'function' token, then try to grab the // token that is the name of the function being defined. // // For every defined function, retain the file and line // location where that function is defined. Since different // modules can define a functions with the same name, // we retain multiple definition locations for each function name. $function_name = safe_arr($next_token, 1, false); $line = safe_arr($next_token, 2, false); if ( $function_name && $line ) { $function_name = trim($function_name); if ( $function_name != "" ) { $defined_functions[$function_name][] = array('file' => $file, 'line' => $line); } } } } } } } // We now have a collection of defined functions and // their definition locations. Go through the tokens again, // and find 'uses' of the function names. foreach ( $tokenized as $file => $tokens ) { foreach ( $tokens as $token ) { if ( is_array($token) && safe_arr($token, 0) == T_STRING ) { $function_name = safe_arr($token, 1, false); $function_line = safe_arr($token, 2, false);; if ( $function_name && $function_line ) { $locations_of_defined_function = safe_arr($defined_functions, $function_name, false); if ( $locations_of_defined_function ) { $found_function_definition = false; foreach ( $locations_of_defined_function as $location_of_defined_function ) { $function_defined_in_file = $location_of_defined_function['file']; $function_defined_on_line = $location_of_defined_function['line']; if ( $function_defined_in_file == $file && $function_defined_on_line == $function_line ) { $found_function_definition = true; break; } } if ( !$found_function_definition ) { // We found usage of the function name in a context // that is not the definition of that function. // Consider the function as 'used'. unset($defined_functions[$function_name]); } } } } } } print_report($defined_functions); exit; // ============================================================================ function php_files($path) { // Get a listing of all the .php files contained within the $path // directory and its subdirectories. $matches = array(); $folders = array(rtrim($path, DIRECTORY_SEPARATOR)); while( $folder = array_shift($folders) ) { $matches = array_merge($matches, glob($folder.DIRECTORY_SEPARATOR."*.php", 0)); $moreFolders = glob($folder.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR); $folders = array_merge($folders, $moreFolders); } return $matches; } // ============================================================================ function safe_arr($arr, $i, $default = "") { return isset($arr[$i]) ? $arr[$i] : $default; } // ============================================================================ function tokenize($file) { $file_contents = file_get_contents($file); if ( !$file_contents ) { return false; } $tokens = token_get_all($file_contents); return ($tokens && count($tokens) > 0) ? $tokens : false; } // ============================================================================ function usage() { global $argv; $file = (isset($argv[0])) ? basename($argv[0]) : "find_unused_functions.php"; die("USAGE: $file <root_directory>\n\n"); } // ============================================================================ function print_report($unused_functions) { if ( count($unused_functions) == 0 ) { echo "No unused functions found.\n"; } $count = 0; foreach ( $unused_functions as $function => $locations ) { foreach ( $locations as $location ) { echo "'$function' in {$location['file']} on line {$location['line']}\n"; $count++; } } echo "=======================================\n"; echo "Found $count unused function" . (($count == 1) ? '' : 's') . ".\n\n"; } // ============================================================================ /* EOF */ 

क्योंकि PHP फ़ंक्शंस / विधियों को गतिशील रूप से लागू किया जा सकता है, निश्चित रूप से पता करने के लिए कोई प्रोग्राममैटिक तरीका नहीं है यदि फ़ंक्शन को कभी भी कॉल नहीं किया जाएगा।

मैनुअल विश्लेषण के माध्यम से केवल एकमात्र तरीका है

afaik वहाँ कोई रास्ता नहीं है यह जानने के लिए कि "कौन से हैं" आपको सिस्टम निष्पादित करने की आवश्यकता होगी (रनटाइम देर से बाध्यकारी फ़ंक्शन लुकअप)।

लेकिन रिफैक्टरिंग टूल स्थिर कोड विश्लेषण पर आधारित हैं। मुझे वास्तव में गतिशील टाइप की गई भाषाएं पसंद हैं, लेकिन मेरे विचार में वे स्केल करने के लिए कठिन हैं। बड़े कोडबेस में सुरक्षित पुनर्संयोजन की कमी और गतिशील टाइप की गई भाषाएं सॉफ्टवेयर विकास के लिए रख-रखाव और हैंडलिंग का एक प्रमुख दोष है।

phpxref यह पता चलेगा कि कार्यों को कहां से कहा जाता है, जिसमें विश्लेषण की सुविधा होगी – लेकिन अभी भी कुछ निश्चित मैनुअल प्रयास शामिल हैं