Doxygen and PHP - how to parse code that is not run? - php

I have some PHP code that is documented with Doxygen. In this code, there are a number of hooks, which are functions that my code calls, but the functions themselves are defined by the users of this code.
I want to document the hooks, but because the functions don't exist in my code (the users define the functions, my code just calls them) there is nowhere for me to attach the Doxygen comments to - unless I define a fake function.
Is there some way I can avoid defining this fake function? If I were using C I could define the function but use #ifdefs to hide it from the compiler (but still have Doxygen see it), but I'm not sure what the equivalent is in PHP. Ideally I'd want something that wouldn't result in any additional effort on the part of the PHP parser.
Any suggestions? This is what I am trying to document, and how I have it now with the fake function:
/// This is an example hook.
/**
* Register it with $hooks['example'][] = 'your_function_name_here';
*
* #param string $dummy
* Dummy parameter.
*/
function hook_example($dummy) { }; // fake function for Doxygen

If you want other programmers to implement your hooks use OOP interfaces and abstract classes. This will sanitize your code.
As a side effect, Doxygen will be very happy to document the abstract methods.

Since PHP doesn't support #ifdef blocks, I think the only way this can be done is to take the comments and fake function declarations and put them in another .php file. Configure Doxygen to include this new file, but don't include() it anywhere in the rest of the code.
Then the fake functions will appear in the documentation, but the PHP parser will never know about them.

Related

Using proxy or shortcuts methods in PHP

I have classes with larges methods name that are called too many times.
Example:
/**
* This class do awesome things.
*/
class AwesomeClass {
/**
* Do something awesome.
*/
public function doSomethingAwesome()
{
//Do something awesome
}
}
Now, I call the method:
$awesomeInstance->doSomethingAwesome();
The method name is large and is typed to many times. For prevent misspelling, I created a shortcut method:
/**
* Shortcut of doSomethingAwesome()
*/
public function dsa()
{
return $this->doSomethingAwesome();
}
And calling method:
$awesomeInstance->dsa();
Is this a bad practice? How afect the performance?
It is a commonly stated rule of thumb that code is read more often than it is written. Even if writing code only for your own use, you will not remember everything about how it works when you read it back in 6 months time to make some amendment.
Your shortcut method names optimise your codebase for writing, because they make it quicker to type, and less error-prone.
However, they are actively harmful for reading, because they lead to less descriptive code, and require you to cross-reference the comment on the shortcut to check what it abbreviates.
Instead, you should aim to write the same code (thus retaining readability) but find tools to do so more easily and with fewer errors. A major helper in this case would be using a more powerful code editor or IDE, which will include auto-complete and code navigation facilities. You can also use standalone "code linting" / "static analysis" tools to pick up mistyped function names.
Performance shouldn't be an issue. But readability of your code suffers. You should use descriptive method names. If this function is called too many times it's a code smell and some refactoring may be needed.
I would not recommend creating shortcut methods. I am not sure why your methods do have such long names. Maybe your methods do more than one task?
for example:
$awesomeInstance->parseCheckAndSaveMyAwsomeObject();
in that case, you should write a dedicated method for each task.
Could you explain it in more detail?

Hooking into function calls in php

A little background: At runtime I would like to be able to inspect the currently called functions javadoc-style documentation, to determine its formal (typed) declaration. This would allow runtime type checking (for simple and complex types) by means of reflection (at a cost) during debugging and testing, something that I would find immensely helpful.
So, in php I would like for a user defined function to get called whenever any other function is about to get called. That is, if a function foo() gets called, I would like to have my callHookHandler() function called immediately before.
One solution would be to implement __call() in all user defined classes, but that is both unwieldy and doesn't include support for functions defined outside classes, so I am looking for a better solution.
This sounds a bit of a fun one so I'm going to give answering it a try.
I hope this helps you. Let me know how it goes.
So, what you are asking can be done, and here's how:
For Functions:
Get all defined functions with $function = get_defined_functions().
Loop through the $functions['user'] key and inspect each one with the ReflectionFunction class. You'll need to get:
The comment using ->getDocComment()
The arguments using ->getParameters()
Do some magic (I'll let you figure out how to parse the comment using some regular extressions and match it up with the parameter list from the reflection. Don't forget optional parameters!)
Rename the function using runkit_function_rename
Generate code in a string that checks the parameters and calls the renamed function
Generate a parameter list as a string
Create a new function with runkit_function_add using the code you generated in step #5 and the parameter list from step #6.
For Classes:
Get a list of classes with $classes = get_declared_classes();
Loop through each one and inspect it with ReflectionObject and ->getMethods() to get the methods. Make sure that the class is not internal with ->isInternal() because we can't do anything about the internal classes.
In an inner loop... go through each method using the ReflectionMethod class. Get the arguments and PHPDoc/JavaDoc comments just like you did with normal functions.
Do the same thing you did with the functions only use runkit_method_add and runkit_method_rename instead.
Downsides:
You won't be able to do the checking on internal class methods and functions (which is fine because they won't have doc comments anyway).
This is a lot of work! I left a lot of parts up to your imagination to avoid this being the length of a short book.
Please send me this or open source it and let me know when you finish, I really want to use this myself. Contact info is on my website which is in my profile ;)
Alternatively:
You can use XDebug's function trace along with reflection then analyze the results after the fact so that you don't have to dynamically edit the code. If you want to write unit-test you could even automate it.
Hope type checking makes it into future versions of PHP and wait: https://wiki.php.net/rfc/typechecking
Notes:
This class reference has a potentially useful example of parsing docComments in the comments section of the page:
http://us.php.net/manual/en/class.reflectionmethod.php
References
get_defined_functions
get_declared_classes
ReflectionFunction
ReflectionObject
ReflectionMethod
runkit
Alternative way to hook into function call is to use a trick with namespaces: Intercepting Execution of System Functions in PHP
You can also use the Go! framework to define an aspect to intercept the execution of system functions automatically.

How to make sections of PHP code in eclipse

I've really only just discovered that you can use /** #blah */ comments to specify certain things, but is it possible to create sections in code?
Like:
/** Start Section "Blah" **/
$result = doSomething();
echo $result;
/** End Section "Blah" */
No PDT can't do that. Generally expandable code sections are identified by function and class method bodies.
If you think you need artificial sections identified by comments I recommend to rather think about reorganizing your code into more fine grained files, function, classes and methods that can be easily documented using PhpDoc (which is the standard PDT uses).
these sections
/**
* here goes your text
* #author Nanne
* /
Are based on javadoc: http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html
Look at this page where a documenter for PHP is described. I don't know what standard is used in Eclipse, but I'm guessing they're all rather alike:
http://www.phpdoc.org/
Is is mostly based on commenting certain parts of code, e.g. classes, functions and variables. As far as I know there is no special code for "sections". The reason I think this, is that you are 'supposed' to make a documentation from this, with classes, it's methods etc. There is no special way to represent "sections" in a documentation like that.
But do read above links, it'll clear up a lot!
In PHP you can use sections to separate pieces of code. Syntax is like this:
Blah:{
$result = doSomething();
echo $result;
}
These were used by goto style procedural programming before object oriented programming was used (classes and instances). Using these sections and goto statements is very bad practice and should be shunned by any developer.
https://www.php.net/manual/en/control-structures.goto.php

Extracting function declarations from a PHP file

I'm looking to create an on-site API reference for my framework and application.
Basically, say I have a class file model.class.php:
class Model extends Object {
... code here ...
// Separates results into pages.
// Returns Paginator object.
final public function paginate($perpage = 10) {
... more code here ...
}
}
and I want to be able to generate a reference that my developers can refer to quickly in order to know which functions are available to be called. They only need to see the comments directly above each function and the declaration line. Something like this (similar to a C++ header file):
// Separates results into pages.
// Returns Paginator object.
final public function paginate($perpage = 10);
I've done some research and this answer looked pretty good (using Reflection classes), however, I'm not sure how I can keep the comments in.
Any ideas?
I want to keep the current comment formatting. Myself and the people who are working on the code hate the verbosity associated with PHPDocumentor. Not to mention a comment-rewrite of the entire project would take years, so I want to preserve just the // comments in plaintext.
Why don't you just run PHPDocumenter on the code?
PHPDoc is identical to JavaDoc, and will retain all the parameters and comments in the docblock above the function.
EDIT: Since you don't want PHPDoc, I think it would probably be easiest to write a RegEx parser to do it, since Reflection won't provide you with any surrounding comments.
PHP code to get the comment:
if(preg_match("#//(.+)$#",$line,$match)>0)
{
echo "Comment is: ".$match[1];
}
this is what phpdoc is for. you comment your code a specific way, following certain rules, and when you're done you run your code through a parser. It outputs exactly what you're looking for.

Documenting a PHP extension with PHPdoc

I've written a PHP extension in C, and I want to create PHPdoc documentation so that my users will get inline docs in their PHP IDE (in this case, Netbeans) when calling my extension.
Ideally I'd like to do this by embedding the PHPdocs in the C code, to keep implementation and documentation together.
Assuming it's possible to embed PHPdocs into the C, what extra steps are needed to make the documentation appear in Netbeans (as it would for PHPdocs of PHP code)?
edit:
O'Reilly Programming PHP refers to the /* {{{ proto comment format being used in doc generation, though I'm not sure if the referred scripts generate PHPdocs:
The {{{ proto line is not only used
for folding in the editor, but is also
parsed by the genfunclist and
genfuncsummary scripts that are part
of the PHP documentation project. If
you are never going to distribute your
extension and have no ambitions to
have it bundled with PHP, you can
remove these comments.
One approach that works is to have a PHP file with stub functions with the appropriate PHPdocs, then DON'T include it in the PHP application, but DO add it to Netbean's PHP include path (in File->Project Properties->PHP Include Path).
This way type completion and inline docs work, but PHP isn't confused by multiple declarations of the function.
This seems a bit hacky, since it would be good keep the docs in the same file as the implementation, but it does actually seem to the correct approach, since that's how the built in functions and extensions are documented - see ~/netbeans-6.7/php1/phpstubs/phpruntime/*.php
eg:
In the C file:
PHP_FUNCTION(myFunctionStringFunction)
{
// extension implementation
}
And then in a PHP file, the stub declaration:
/**
* My docs here
* #param string $myString
*/
function myFunctionStringFunction($myString)
{
die("Empty stub function for documenation purposes only. This file shouldn't be included in an app.");
}
you only need to use the right TAGS inside your Comments.
/**
* Returns the OS Languages for an Subversion ID
*
* #access public
* #param int $subVersionId Subversion ID
* #return array $results Languages for Subversion ID
*/
You can find all available tags on the documenation
PHPDoc
I think it is possible to use Reflection API to generate the prototype file, though I could not find existing code that does exactly that.
As written in extension skeleton:
/* {{{ */ and /* }}} */
The previous line is meant for vim and emacs, so it can correctly fold
and unfold functions in source code. See the corresponding marks just
before function definition, where the functions purpose is also
documented. Please follow this convention for the convenience of
others editing your code.

Categories