build list of available functions and classes

From: Date: Thu, 30 Dec 2004 02:45:19 +0000
Subject: build list of available functions and classes
Groups: php.general 
Request: Send a blank email to php-general+get-205338@lists.php.net to get a copy of this message
Hello, for the purpose of automatically building a syntax highlighting file for jEdit I wanted to write a script that does this automatically by retrieving http://php.net/quickref.php and extracting it. Unfortunately the syntax for the function names there is not trivial. For example, the swfbitmap::getheight() is named (content of the <a> tag) swfbitmap.getheight in the list. This is great and could be easily detected (because of the point). But AFAICS the SWF classes are the only ones that use this naming convention. So I've taken the output from PHP 5.0.3's get_declared_classes() and test if the part of the function name before the first '_' is one of those classes and handle it as a class function then (cut the class name in front). Another problem are the old DOM-XML class functions that are prefixed with 'dom_', which I optionally match in the regexp. Wouldn't it be easier to use the syntax "class.function_name" for the names? I've attached the script, so you can probably better understand what I mean.. ;) -- happy new year!

<?php /** * This script gets the PHP function list from php.net, the alias list from * zend.org and builds keyword blocks for jEdit's php.xml mode file. * * @author daniel hahler (http://thequod.de/contact) * @version 2004-12-30 */ error_reporting(E_ALL); $urls = array( 'quickref' => 'http://www.php.net/quickref.php', 'aliases' => 'http://zend.com/phpfunc/all_aliases.php', ); /** * @var array holds all functions */ $functions = array(); /** * @var array holds all functions for classes (classnames are keys) */ $functionsForClasses = array( // {{{ 'arrayiterator' => array(), 'arrayobject' => array(), 'cachingiterator' => array(), 'cachingrecursiveiterator' => array(), 'com' => array(), 'compersisthelper' => array(), 'com_exception' => array(), 'com_safearray_proxy' => array(), 'directory' => array(), 'directoryiterator' => array(), 'domattr' => array(), 'domcdatasection' => array(), 'domcharacterdata' => array(), 'domcomment' => array(), 'domconfiguration' => array(), 'domdocument' => array(), 'domdocumentfragment' => array(), 'domdocumenttype' => array(), 'domdomerror' => array(), 'domelement' => array(), 'domentity' => array(), 'domentityreference' => array(), 'domerrorhandler' => array(), 'domexception' => array(), 'domimplementation' => array(), 'domimplementationlist' => array(), 'domimplementationsource' => array(), 'domlocator' => array(), 'domnamednodemap' => array(), 'domnamelist' => array(), 'domnamespacenode' => array(), 'domnode' => array(), 'domnodelist' => array(), 'domnotation' => array(), 'domprocessinginstruction' => array(), 'domstringextend' => array(), 'domstringlist' => array(), 'domtext' => array(), 'domtypeinfo' => array(), 'domuserdatahandler' => array(), 'domxpath' => array(), 'dotnet' => array(), 'exception' => array(), 'filteriterator' => array(), 'limititerator' => array(), 'parentiterator' => array(), 'php_user_filter' => array(), 'recursivedirectoryiterator' => array(), 'recursiveiteratoriterator' => array(), 'reflection' => array(), 'reflectionclass' => array(), 'reflectionexception' => array(), 'reflectionextension' => array(), 'reflectionfunction' => array(), 'reflectionmethod' => array(), 'reflectionobject' => array(), 'reflectionparameter' => array(), 'reflectionproperty' => array(), 'simplexmlelement' => array(), 'simplexmliterator' => array(), 'sqlitedatabase' => array(), 'sqliteexception' => array(), 'sqliteresult' => array(), 'sqliteunbuffered' => array(), 'variant' => array(), // autodetect-classes ("class.function" syntax) without methods (to get removed) 'swfaction' => array(), /** * @obsolete PHP4 */ 'domattribute' => array(), 'domxsltstylesheet' => array(), ); // }}} // Get PHP's quickref-list and extract it {{{ $buffer = file_get_contents( $urls['quickref'] ); preg_match_all( '#<a href="/manual/en/function\.[^>]+>(?:(\w+)\.)?(\w+)</a>#', $buffer, $matches, PREG_PATTERN_ORDER ); foreach( $matches[2] as $lKey => $lFunction ) { if( !empty( $matches[1][$lKey] ) ) { // this is a class function ("class.function") $functionsForClasses[$matches[1][$lKey]][] = $lFunction; } elseif( preg_match( '#^(?:dom_)?([a-z]+)_(.*)$#', $lFunction, $match ) && isset( $functionsForClasses[$match[1]] ) ) { // this is also a class function, not divided with a dot $functionsForClasses[$match[1]][] = $match[2]; } else { addFunction( $lFunction ); } } // }}} // Remove constructors from function list (those that have been discovered // through class.function syntax foreach( array_keys($functions) as $lFunction ) { if( isset( $functionsForClasses[$lFunction] ) ) { unset( $functions[$lFunction] ); } } // Get Zend's Alias list and extract it {{{ $buffer = file_get_contents( $urls['aliases'] ); preg_match_all( '#<tr[^>]*>' .'<td[^>]*><a href="[^"]*function.\w+.php">(\w+)</a></td>' // alias .'<td><a [^>]+>[^<]+</a></td>' // source .'<td><a href="function.*?">\w+</a></td></tr>#', // orig $buffer, $matches, PREG_PATTERN_ORDER ); $aliases = isset( $matches[1] ) ? array_unique($matches[1]) : array(); natsort( $aliases ); // }}} /** * Internal function to echo a keyword */ function echo_keyword( $keyword, $nr = '2', $srcArray = NULL ) { echo "\t\t\t<KEYWORD$nr>$keyword</KEYWORD$nr>"; if( is_array( $srcArray ) && isset($srcArray[0]) ) { echo ' <!-- '.implode( ', ', $srcArray ).' -->'; } echo "\n"; } function addFunction( $name, $src = NULL ) { global $functions; $_src = isset( $functions[$name] ) ? $functions[$name]['src'] : array(); if( !is_null( $src ) ) { if( !is_array( $src ) ) { $_src[] = $src; } else { $_src = array_merge( $_src, $src ); } } $functions[$name]['src'] = $_src; } ksort($functionsForClasses); echo "\t\t\t<!-- Internal classes (".count( $functionsForClasses ).") -->\n"; foreach( $functionsForClasses as $lClass => $lFunctions ) { echo_keyword( $lClass ); // add the class functions to the global list foreach( $lFunctions as $lFunction ) { addFunction( $lFunction, $lClass ); } } uksort( $functions, 'strnatcasecmp' ); echo "\n\t\t\t<!-- Internal functions (".count( $functions ).") -->\n"; foreach( $functions as $lFunction => $lValue ) { echo_keyword( $lFunction, '2', $lValue['src'] ); } if( $count = count( $aliases ) ) { // Output aliases echo "\n\t\t\t<!-- Alias functions (".count( $aliases ).") -->\n"; foreach( $aliases as $lAlias ) { echo_keyword( $lAlias, '4' ); } } ?>
« previous php.general (#205338) next »