Page 1 of 1

Auto-link to php.net from function names in text

Posted: Tue Jul 12, 2005 12:29 pm
by Chris Corbyn
I got bored today at work so threw this together. Perhaps it could be implemented to make a phpBB mod or something or other although it would need work to avoid BBCode clashes (it might go nicely in a PHP Blog too ;)). I dunno, if you want it, here's what it does. It gathers the PHP function info into a database and then checks given HTML/Text for matches of the function names and converts them to hyperlinks to the php.net manual page for the function. It also adds a "title" attribute containing the function usage - a *cough* cheap tooltip ;)


----------
Stage 1 (one-off data extraction - update when new php versions are released if you want):

This stage rips information from the PHP manual download. It extracts all the function names and the description on how they are used (i.e. array_keys (array array)) and dumps the data into a mysql table. You need to give it your database info as arguments and make sure you DON'T have table named `phpfuncs` in there already. Make sure you get the "multiple HTML files" version of the manual and extract it somewhere PHP has access to read.

You can get the multiple file version here: http://uk.php.net/get/php_manual_en.tar ... his/mirror (2005-07-12)

$path is the path to the manual files
$user, $pass, $db, and $server are the MySQL database credentials.

You need only run this function once.

Code: Select all

<?php

/*
 Written by d11wtq of http://forums.devnetwork.net
 
 Grabs details of ALL the documented functions for PHP
 -- using the latest HTML download version of the manual
 -- (multiple files version).
 The data is dumped into a given database in a table named
 -- `phpfuncs`.
 */
 
//This could take some time, better to increase the time limit
set_time_limit(100);

//Path requires the trailing FORWARD slash (I couldn't be bothered to check for it)
function grabNdumpPHPFuncs($path, $user, $pass, $db, $server='localhost') {
	
	$conn = mysql_connect($server, $user, $pass) or die ('Error connecting to database.');
	
	mysql_select_db($db, $conn) or die ('Error selecting database.');
	
	//Create a new table ready for the insert
	$create_query = &quote;
	CREATE TABLE `phpfuncs` (
	  `id` int(4) auto_increment,
	  `fname` varchar(30) not null,
	  `fdesc` varchar(120) not null,
	  PRIMARY KEY(`id`)
	)
	&quote;;
	
	mysql_query($create_query) or die (mysql_error());
	
	if (is_dir($path)) {
		
		if (false === $handle = opendir($path)) {
			die ('Error opening directory, does PHP have permission?');
		} //End if
		
		$count = 0;
		while (false !== $file = readdir($handle)) {
		
			if (preg_match('/^function\.(.*?)\.html$/', $file, $m)) {
			
				$name = str_replace('-', '_', $mї1]); //file-get-contents => file_get_contents
				
				$htmlData = file_get_contents($path.$file);
				
				preg_match('#><H2\s*>Description</H2\s*>.*?<B\s*CLASS=&quote;methodname&quote;\s*>(.*?)</B\s*>(.*?)<BR#is', $htmlData, $n); //Extract the usage part
				
				if (!isset($nї1])) $nї1] = '';
				if (!isset($nї2])) $nї2] = '';
				$desc = $nї1].$nї2]; //Rebuild the function usage info
				
				$insert_query = &quote;
				INSERT INTO `phpfuncs` (
				  `fname`,
				  `fdesc`
				) VALUES (
				  '$name',
				  '$desc'
				)
				&quote;;
				mysql_query($insert_query) or die(mysql_error()); //Add the row
				$count++;
				
			} //End if
			
		} //End while
		
		closedir($handle); //Finish reading the dir
		
	} else {
		die ($path.' does not appear to be a valid path.');
	} //End if
	
	mysql_close($conn);
	
	echo 'Done processing '.$count.' records.<br />';
	
	return true;
	
}

/* EOF */
 
?>
Stage 2 (Either before adding to DB or when displaying on web page):

This searches given text and adds the code required to show hyperlinks and tooltips. It's not slow but it's probably best to do it before storing the data into a database.

It takes $conn as an argument which should be an established MySQL connection to the database with the database selected ready for use.

----------

Code: Select all

<?php

/*
 Written by d11wtq of http://forums.devnetwork.net/
 
 For this to work you must first have run the 
 -- grabNdumpPHPFuncs() function to create the database.
 
 Converts plain text PHP function names into hyperlinks
 -- to the relevant manual page.
 
 $conn should be the resource ID for the connection
 -- to the database containing the `phpfuncs` table.
 */
 
function PHPFunction2Hyperlink($text, $conn) {

	$query = &quote;
	SELECT
	  `fname`,
	  `fdesc`
	FROM
	  `phpfuncs`&quote;;
	
	$result = mysql_query($query, $conn) or die (mysql_error());
	
	$tokens = preg_split('/\b/', $text); //Tokenize the regex way 
	
	$stash = array();
	while ($values = mysql_fetch_assoc($result)) {
	
		$stashї$valuesї'fname']] = $valuesї'fdesc'];
		
	} //End while
	
	foreach ($tokens as $i => $v) {
		if (array_key_exists($v, $stash)) {

			if (isset($tokensї$i+1])) {

				if (preg_match('/\(\)(\s*)/', $tokensї$i+1], $m)) { //The parens are immediately next in queue
					$tokensї$i] .= $tokensї$i+1]; //Combine
					unset($tokensї$i+1]); //Remove next item
				} //End if

			} //End if

			//Make our nice link to php.net
			$tokensї$i] = '<a href=&quote;http://www.php.net/'.$v.'&quote; title=&quote;'.$stashї$v].'&quote;>'.rtrim($tokensї$i]).'</a>'.$mї1];

		} //End if
	} //End foreach
	
	return implode('', $tokens); //Rebuild the string
}

/* EOF */

?>
Hmm... well it was something to do :P

Posted: Tue Jul 12, 2005 1:09 pm
by Chris Corbyn
Example use:

First thing I need to do, even if I only do it once is to make a table in a mysql database. The first script does this. So lets say I download the manual from php.net and extract it to "public_html/". It creates the subdirectory "public_html/html/". I also have a database called `exampleDB` to create the table in.

Here goes (I'm running the script from the "public_html/" folder...

Code: Select all

<?php
include('grabNdumpPHPFuncs.function.php');
grabNdumpPHPFuncs('./html/', 'username', 'password', 'exampleDB', 'localhost');
?>
That's it! Just run it - be patient, depending upon your system it may take a while. When it's done it tells you how many rows it created and if you look in the database you'll see the table `phpfuncs` with over 4000 rows in it. Now we have a database we can get away with never doing this part ever again.

All i have to do now is put it to use with the second script.

Imagine I'm receiving what's in my HEREDOC as form input from a textarea ... this just makes it easier to follow what happened though ;)

Code: Select all

$conn = mysql_connect('localhost', 'username', 'password');
mysql_select_db('exampleDB');

//Do some nice things in my script.... yadda yadda

//Take some string we want to convert
$text = <<<EOD
I'm just writing any old rubbish merely so I can demonstrate how this function works.

The way to use the function is to include() the script into the script you'll be using it in.

You'll first have need to have run the first script in order to create a database with all the functions
in the latest version of PHP given.

You'll get a replaced version of the text you give it which contains hyperlinks to php.net.

If you were taking input from a textarea it might be an idea to run nl2br on the returned string.

Enjoy!
EOD;


//Run the converter
include('PHPFunction2Hyperlink.function.php');
echo PHPFunction2Hyperlink($text, $conn);

mysql_close();
Which outputs this....

Code: Select all

I'm just writing any old rubbish merely so I can demonstrate how this function works.

The way to use the function is to &lt;a href=&quote;http://www.php.net/include&quote; title=&quote;&quote;&gt;include()&lt;/a&gt; the script into the script you'll be using it in.

You'll first have need to have run the first script in order to create a database with all the functions
in the latest version of PHP given.

You'll get a replaced version of the text you give it which contains hyperlinks to php.net.

If you were taking input from a textarea it might be an idea to run &lt;a href=&quote;http://www.php.net/nl2br&quote; title=&quote;nl2br ( string string )&quote;&gt;nl2br&lt;/a&gt; on the returned string.

Enjoy!

Posted: Wed Jul 13, 2005 3:27 am
by onion2k
Nice.

One thing I'd add .. "It's not slow but it's probably best to do it before storing the data into a database." .. Better still, store the original text AND the modified text with the links to the manual. That way you can still edit easily without having to strip out links first.

Posted: Wed Jul 13, 2005 5:17 am
by Chris Corbyn
Yeah that's true. Especially for something like phpBB where posts can be editted.

If it's going to be used for a mod or something it WILL need some work...