I’ve been trying to get the comments out of a certain .php
file on my server, in order to parse its variables. I thought Ii found an easy way to do this, however, the function I use doesn’t return anything, even though I clearly have comments in the file.
Here are the comments I use:
/** * @param foo bar * @return baz */
Here’s my code:
function GetComments($filename) { $expr = "/((?:/*(?:[^*]|(?:*+[^*/]))**+/)|(?://.*))/"; $file = fopen($filename, "r"); $length = filesize($filename); $comments = fread($file, $length); fclose($file); preg_match_all($expr, $comments, $matches); foreach($matches[0] as $id => $variable) { $comments = str_replace($variable, '', $comments); } return $comments; }
Is there something I’m doing wrong? Because if so, I’m clearly over looking it.
Any help would be very welcome.
I found an answer:
First of all, I should have probably noted in my question that I am trying to write a system for reading plugins. These plugin files should contain a comment block at the top containing variables like the plugin’s author, website, email, etc.
So here’s what I did:
I took feeela’s example to change my function to get the comments and its variables.
I then changed its code a bit to fit my needs:
public function GetComments($filename) { $docComments = array_filter(token_get_all(file_get_contents($filename)), function($entry) { return $entry[0] == T_COMMENT; }); $fileDocComment = array_shift($docComments); $regexp = "/@.*:s.*r/"; preg_match_all($regexp, $fileDocComment[1], $matches); for($i = 0; $i < sizeof($matches[0]); $i++) { $params[$i] = split(": ", $matches[0][$i]); } return($params); }
I put the result of the code feeela gave me through a regular expression match, resulting in an array containing the parameters and their values combined.
Then I used the split function to actually give me separated parameters and values, so I could return them to the variable that called the function.
In order to get this to work properly, I needed to change the comment style I used from
/** * @param foo bar * @return baz */
to
/* @param: foo bar @return: baz */
making it a normal comment block, instead of a doc comment block. And it also enabled me to use ‘: ‘ as a pattern for the split function.
It might be ‘not so efficient’ in the eyes of some. As feeela noted, “what if your comment style changes?”. I will be the only one working on this project and writing the plugins. Therefore it will not be too hard for me too keep the comment style the same in every plugin script.
This method works perfectly for me.
Advertisement
Answer
You can use token_get_all(), which “parses a given PHP source string into language tokens using the Zend engine’s lexical scanner”.
Here’s an example function I’ve used once to get the file-doc-comment from the current file:
/** * Return first doc comment found in this file. * * @return string */ function getFileDocBlock() { $docComments = array_filter( token_get_all( file_get_contents(__FILE__)), function($entry) { return $entry[0] == T_DOC_COMMENT; } ); $fileDocComment = array_shift($docComments); return $fileDocComment[1]; }