Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 53 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
53
Dung lượng
8,79 MB
Nội dung
CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 351 property). It also includes special keywords called tags. Tags are defined using the at sign (@) and may be associated with arguments. So the following DocBlock placed at the top of a class tells phpDocumentor the package to which it belongs: /** * @package command */ If I add this comment to every class in my project (with the appropriate package name, of course), phpDocumentor will organize our classes for us. You can see phpDocumentor output that includes packages in Figure 16–3. Figure 16–3. Documentation output that recognizes the @package tag In Figure 16–3, notice that packages have been added to the navigation (top-right corner). In addition to the default megaquiz package I defined as a command line switch, I can now click command or quiztools. Because I am currently examining classes in the command package, the links that form the left- hand navigation list only those classes. Generally, packages in documentation will mirror your directory structure. So the command package maps to a command directory. That isn’t necessary, however. A third-party developer may wish to create a Command class that is part of the command package but lives in her own directory, for example. So the @package tag makes you take responsibility for associating classes with packages, but it also affords you flexibility that would not be available by using the file system to guess at package names. CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 352 Documenting Classes Let’s add some more tags and text that are useful in class- or file-level DocBlocks. I should identify the class, explain its uses, and add authorship and copyright information. Here is the Command class in its entirety: /** * Defines core functionality for commands. * Command classes perform specific tasks in a system via * the execute() method * * @package command * @author Clarrie Grundie * @copyright 2004 Ambridge Technologies Ltd */ abstract class Command { abstract function execute( CommandContext $context ); } The DocBlock comment has grown significantly. The first sentence is a one-line summary. This is emphasized in the output and extracted for use in overview listings. The subsequent lines of text contain more detailed description. It is here that you can provide detailed usage information for the programmers who come after you. As we will see, this section can contain links to other elements in the project and fragments of code in addition to descriptive text. I also include @author and @copyright tags, which should be self-explanatory. You can see the effect of my extended class comment in Figure 16–4. Figure 16–4. Class details in documentation output CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 353 Notice that I didn’t need to tell phpDocumentor that the Command class is abstract. This confirms something that we already know, that phpDocmentor interrogates the classes with which it works even without our help. But it is also important to see that DocBlocks are contextual. phpDocumentor understands that we are documenting a class in the previous listing, because the DocBlock it encounters immediately precedes a class declaration. ■Note At the time of this writing, phpDocumentor does not support namespaces. However, the project’s maintainer, Greg Beaver, is on record as committed to provide this functionality (< http://lists.bluga.net/pipermail/phpdocumentor-devel/2008-September/000066.html>). File-Level Documentation Although I tend to think in terms of classes rather than of the files that contain them, there are good reasons in some projects for providing a layer of documentation at the file level. First of all, phpDocumentor likes file comments. If you fail to include a DocBlock for a file in your project, a warning is raised that can clutter up the application’s reporting, especially in large projects. A file comment should be the first DocBlock in a document. It should contain a @package tag, and it should not directly precede a coding construct. In other words, if you add a file-level DocBlock, you should ensure that you also add a class-level comment before the first class declaration. Many open source projects require that every file includes a license notice or a link to one. Page- level DocBlock comments can be used, therefore, for including license information that you do not want to repeat on a class-by-class basis. You can use the @license tag for this. @license should be followed by a URL, pointing to a license document and a description: /** * @license http://www.example.com/lic.html Borsetshire Open License * @package command */ The URL in the license tag will become clickable in the phpDocumentor output. Documenting Properties All properties are mixed in PHP. That is, a property can potentially contain a value of any type. There may be some situations in which you require this flexibility, but most of the time, you think of a property as containing a particular data type. phpDocmentor allows you to document this fact using the @var tag. Here are some properties documented in the CommandContext class: class CommandContext { /** * The application name. * Used by various clients for error messages, etc. * @var string */ public $applicationName; /** CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 354 * Encapsulated Keys/values. * This class is essentially a wrapper for this array * @var array */ private $params = array(); /** * An error message. * @var string */ private $error = ""; // As you can see, I provide a summary sentence for each property and fuller information for the first two. We use the @var tag to define each property’s type. If we were to use the same phpdoc command line arguments as usual to generate output at this point, you would only see documentation for the public $applicationName property. This is because private methods and properties do not appear in documentation by default. Whether or not you choose to document private elements depends in large part on your intended audience. If you are writing for client coders, then you should probably hide your classes’ internals. If, on the other hand, your project is under development, your team members may need more detailed documentation. You can make phpDocumentor include private elements by using the -pp ( parseprivate) command line argument when you invoke the script: phpdoc -d /home/projects/megaquiz/ \ -t /home/projects/docs/megaquiz/ \ -ti 'Mega Quiz' \ -dn 'megaquiz' \ -pp on Notice that you must explicitly set the -pp flag to on; it is not enough to include the flag on its own. You can see the documented properties in Figure 16–5. CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 355 Figure 16–5. Documenting properties Documenting Methods Together with classes, methods lie at the heart of a documentation project. At the very least, readers need to understand the arguments to a method, the operation performed, and its return value. As with class-level DocBlock comments, method documentation should consist of two blocks of text: a one-line summary and an optional description. You can provide information about each argument to the method with the @param tag. Each @param tag should begin a new line and should be followed by the argument name, its type, and a short description. Because PHP does not constrain return types, it is particularly important to document the value a method returns. You can do this with the @return tag. @return should begin a new line and should be followed by the return value’s type and a short description. I put these elements together here: /** * Perform the key operation encapsulated by the class. * Command classes encapsulate a single operation. They * are easy to add to and remove from a project, can be * stored after instantiation and execute() invoked at * leisure. * @param $context CommandContext Shared contextual data * @return bool false on failure, true on success */ CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 356 abstract function execute( CommandContext $context ); It may seem strange to add more documentation than code to a document. Documentation in abstract classes is particularly important, though, because it provides directions for developers who need to understand how to extend the class. If you are worried about the amount of dead space the PHP engine must parse and discard for a well-documented project, it is a relatively trivial matter to add code to your build tools to strip out comments on installation. You can see our documentation’s output in Figure 16–6. Figure 16–6. Documenting methods Creating Links in Documentation phpDocumentor generates a hyperlinked documentation environment for you. Sometimes, though, you will want to generate your own hyperlinks, either to other elements within documentation or to external sites. In this section, we will look at the tags for both of these and encounter a new syntax: the inline tag. As you construct a DocBlock comment, you may want to talk about a related class, property, or method. To make it easy for the user to navigate to this feature, you can use the @see tag. @see requires a reference to an element in the following format: class class::method() or like this: class::$property CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 357 So in the following DocBlock comment, I document the CommandContext object and emphasize the fact that it is commonly used in the Command::execute() method: /** * Encapsulates data for passing to, from and between Commands. * Commands require disparate data according to context. The * CommandContext object is passed to the Command::execute() * method and contains data in key/value format. The class * automatically extracts the contents of the $_REQUEST * superglobal. * * @package command * @author Clarrie Grundie * @copyright 2004 Ambridge Technologies Ltd * @see Command::execute() */ class CommandContext { // As you can see in Figure 16–7, the @see tag resolves to a link. Clicking this will lead you to the execute() method. Figure 16–7. Creating a link with the @see tag CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 358 Notice, though, that we also embedded a reference to Command::execute() in the DocBlock description text. We can transform this into a live link by using the @link tag. @link can be added at the beginning of a line, as @see is, but it can also be used inline. In order to differentiate inline tags from their surroundings, you must surround them with curly brackets. So, to make my embedded reference to Command::execute() clickable, I would use the following syntax: // * Commands require disparate data according to context. The * CommandContext object is passed to the {@link Command::execute()} * method and contains data in key/value format. The class // Because the @link tag in the previous fragment includes only the element reference (Command::execute()), it is this string that becomes clickable. If I were to add some description here, it would become clickable instead. @link can be used to refer to URLs as well. Simply replace the element reference with a URL: @link http://www.example.com More info Once again, the URL is the target, and the description that follows it is the clickable text. You may want to make a reciprocal link. Command uses CommandContext objects, so I can create a link from Command::execute() to the CommandContext class and a reciprocal link in the opposite direction. I could, of course, do this with two @link or @see tags. @uses handles it all with a single tag, however: /** * Perform the key operation encapsulated by the class. * * @param $context {@link CommandContext} Shared contextual data * @return bool false on failure, true on success * @link http://www.example.com More info * @uses CommandContext */ abstract function execute( CommandContext $context ); In adding the @uses tag, I create a link in the Command::execute() documentation: “Uses: CommandContext”. In the CommandContext class documentation, a new link will appear: “Used by: Command::execute()”. You can see the latest output in Figure 16–8. Note that I have not used @link inline, so it is output in list format. CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 359 Figure 16–8. Documentation including @link and @uses tags Summary In this chapter, I covered the core features of phpDocumentor. You encountered the DocBlock comment syntax and the tags that can be used with it. I looked at approaches to documenting classes, properties, and methods, and you were provided with enough material to transform your documentation, and thus improve collaborative working immeasurably (especially when used in conjunction with build tools and version control). There is a lot more to this application than I have space to cover, though, so be sure to check the phpDocumentor homepage at http://www.phpdoc.org. CHAPTER 16 ■ GENERATING DOCUMENTATION WITH PHPDOCUMENTOR 360 [...]... megaquiz/trunk/megaquiz.orig/tags Adding megaquiz/branches Adding megaquiz/quiztools Adding megaquiz/quiztools/AccessManager .php Adding megaquiz/main .php Adding megaquiz/command Adding megaquiz/command/Command .php Adding megaquiz/command/FeedbackCommand .php Adding megaquiz/command/CommandContext .php Adding megaquiz/command/LoginCommand .php Adding megaquiz/tags Committed revision 1 Now that you have imported your project, you should... megaquiz-branch1.0.0/command A megaquiz-branch1.0.0/command/Command .php A megaquiz-branch1.0.0/command/CommandContext .php A megaquiz-branch1.0.0/command/FeedbackCommand .php A megaquiz-branch1.0.0/command/LoginCommand .php Checked out revision 10 I moved out of the megaquiz-trunk directory before checking out the branch Now I have two directories at the same level: megaquiz-trunk contains the trunk, and I’ll commit... megaquiz1.0.0/command/CommandContext .php megaquiz1.0.0/command/FeedbackCommand .php megaquiz1.0.0/command/LoginCommand .php Exported revision 9.The first argument to export specifies the source In this case, the tag I created in the last section The second argument specifies a destination directory which Subversion will create if necessary Branching a Project Now that my project has been released, I can pack it away and. .. subcommand to generate clean release versions of your codebase $ svn export svn+ssh://localhost/var/local/svn/megaquiz/tags/megaquiz-release1.0.0 \ megaquiz1.0.0 A A A A A A A A A A A megaquiz1.0.0 megaquiz1.0.0/quizobjects megaquiz1.0.0/quizobjects/User .php megaquiz1.0.0/quiztools megaquiz1.0.0/quiztools/AccessManager .php megaquiz1.0.0/main .php megaquiz1.0.0/command megaquiz1.0.0/command/Command .php. .. 'added doc level comment' Sending quizobjects/User .php Transmitting file data I use the commit subcommand to check new data into the Subversion repository Notice that I used the -m switch to add a message on the command line, rather than via an editor Now it’s Bob’s turn to update and commit: $ svn update quizobjects/User .php Conflict discovered in 'quizobjects/User .php' Select: (p) postpone, (df) diff-full,... must take account of this, allowing users to add new files and remove deadwood that would otherwise get in the way Adding a File You can add a new document to Subversion with the add subcommand Here I add a document called Question .php to the project: $ touch quizobjects/Question .php $ svn add quizobjects/Question .php A quizobjects/Question .php 371 CHAPTER 17 ■ VERSION CONTROL WITH SUBVERSION In a real-world... development Subversion allows you to maintain parallel strands of development in a project I can continue working on as before in the trunk It is here that I add new and experimental code Let’s use a particular file, command/FeedbackCommand .php, as an example class FeedbackCommand extends Command { function execute( CommandContext $context ) { // new and risky development // goes here 374 CHAPTER 17 ■ VERSION... come as no surprise to learn that you can use a subcommand called remove $ svn remove quizobjects/Question .php D quizobjects/Question .php Once again, a commit is required to finish the job $ svn commit -m'removed Question' Deleting quizobjects/Question .php Committed revision 6 Adding a Directory You can also add and remove directories with add and remove Let’s say Bob wants to make a new directory... update U quizobjects/User .php Updated to revision 3 Subversion visits every directory in the project, finding nothing to update until it encounters the document User .php Bob’s changes are then incorporated into my version of the document You can commit globally in the same way In this example, I have made minor changes to two documents, command/Command .php and quiztools/AccessManager .php: $ svn commit... add file and class comments I begin by adding the file comment to my version of the file: < ?php /** * @license * @package */ http://www.example.com Borsetshire Open License quizobjects class User {} ?> Meanwhile, working in his own sandbox, Bob is keen as ever, and he has created the class comment: < ?php /** * @package quizobjects */ class User {} ?> So we now have two distinct versions of User .php At . megaquiz/quiztools/AccessManager .php Adding megaquiz/main .php Adding megaquiz/command Adding megaquiz/command/Command .php Adding megaquiz/command/FeedbackCommand .php Adding megaquiz/command/CommandContext .php Adding. passing to, from and between Commands. * Commands require disparate data according to context. The * CommandContext object is passed to the Command::execute() * method and contains data. message on the command line, rather than via an editor. Now it’s Bob’s turn to update and commit: $ svn update quizobjects/User .php Conflict discovered in 'quizobjects/User .php& apos;. Select: