The Workshop: Producing Packages (Part 2) - php[architect] Magazine November 2018

Joe • September 2, 2020

learning packages phparch writing php

Warning:

This post content may not be current, please double check the official documentation as needed.

This post may also be in an unedited form with grammatical or spelling mistakes, purchase the November 2018 issue from http://phparch.com for the professionally edited version.

The Workshop: Producing Packages (Part 2)

by Joe Ferguson

Last month we started building PHP Easy Math, a small library which can be included in PHP projects to provide simple methods to do basic addition and subtraction. We're using this as an example library to focus on what makes a library "good" we are less worried about the practical need for and usage of our package.

What Did We Forget?

If you have not yet read Part 1 pause here and go read The Workshop: Producing Packages (Part 1). Head over to https://github.com/svpernova09/php-easy-math to get the library code.

At the end of the previous article I asked readers what we forgot to do in our library and to reach out to me on Twitter with the answer. I'm happy to say MemphisPHP user group leader Bryce Sharp was the first to answer correctly:

11-2018-producing-packages.png

Pick a License

Licensing any code you write is incredibly important. Even if you're not sharing code with the entire open source world you still should have a license. If you are sharing open source code and there is no license which means no one is allowed to do anything with your code! To sort through software licenses I highly recommend reading Choose a License. Choose a License does a great job of explaining the benefits of different open source licenses. However if you do not put a license on your code it is considered proprietary software and is unable to be used by anyone. The act of using a permissive license if you are expressly granting approval for others to use your code.

Since our PHP Easy Math library is a very basic package we are using for learning, we're going to add the MIT License to the library. This will allow anyone to use our library in their own projects or modify our code to suite their needs. However our copyright must remain intact. You can see we added our LICENSE file in the repository.

One last housekeeping task we're going to perform is to rename our README file to README.md. We're using Markdown but Github is not rendering our markdown because we do not have a file extension. Once we have renamed the file our contents will be rendered as we'd expect and not just as plain text.

Documentation is Key

Do you expect potential users of your library to read the source code? Of course not, documentation is important. It's the best way to ensure your code is easy to understand by other developers. You'll also ensure you're explaining anything which may not be perfectly obvious to someone else reading or using the code without getting bogged down in the internal workings.

In our haste to create our library we forgot to document our add() and subtract() methods. While these are not overly complex methods we should still add documentation blocks (doc blocks) to help IDEs with auto completion as well as generating our documentation:

Addition:

/**
 * Sum 2 numbers
 *
 * @param float $x
 * @param float $y
 * @return float
 */
public function add($x, $y)
{
    return $x + $y;
}

Subtraction:

/**
 * Subtract 2 numbers
 * @param float $x
 * @param float $y
 * @return float
 */
public function subtract($x, $y)
{
    return $x - $y;
}

The doc blocks allow us to specify what our method is going to do "Sum 2 numbers" as well as what types we expect our parameters to be (floats) and we plan to return a value of the float type. While these types will not be honored at run time, many editors and IDEs (such as JetBrains' PhpStorm) will read the doc blocks and show warnings and hints based on their value. You can read more about doc blocks and all the different options on the phpdoc.org site.

Taking our doc blocks to the next step we can install phpDocumentor and GraphViz so we can run the phpdoc.phar binary against our src folder to generate our documentation for us. Usage of phpdoc.phar is to call the phar file, supply a source directory of code to parse, and specify an output folder to write the HTML docs to. We'll run the command like so:

$ php phpdoc.phar -d ./src -t ./docs

And get the output below.

Collecting files .. OK
Initializing parser .. OK
Parsing files
Parsing /Users/joeferguson/PhpstormProjects/php-easy-math/src/Subtraction.php
Parsing /Users/joeferguson/PhpstormProjects/php-easy-math/src/Addition.php
Storing cache in "/Users/joeferguson/PhpstormProjects/php-easy-math/docs" .. OK
Load cache                                                         ..    0.003s
Preparing template "clean"                                         ..    0.004s
Preparing 17 transformations                                       ..    0.000s
Build "elements" index                                             ..    0.000s
Replace textual FQCNs with object aliases                          ..    0.000s
Resolve @link and @see tags in descriptions                        ..    0.000s
Enriches inline example tags with their sources                    ..    0.000s
Build "packages" index                                             ..    0.001s
Build "namespaces" index and add namespaces to "elements"          ..    0.000s
Collect all markers embedded in tags                               ..    0.000s
Transform analyzed project into artifacts                          ..
Applying 17 transformations
  Initialize writer "phpDocumentor\Plugin\Core\Transformer\Writer\FileIo"
  Initialize writer "phpDocumentor\Plugin\Twig\Writer\Twig"
  Initialize writer "phpDocumentor\Plugin\Graphs\Writer\Graph"
  Execute transformation using writer "FileIo"
  Execute transformation using writer "FileIo"
  Execute transformation using writer "FileIo"
  Execute transformation using writer "FileIo"
  Execute transformation using writer "FileIo"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "twig"
  Execute transformation using writer "Graph"
   0.464s
Analyze results and write report to log                            ..    0.000s

Now we have a docs/ folder containing the output from phpdoc.phar.

11-2018-producing-packages-2.png

If we open the docs/index.html file in a web browser we see our generated documentation.

11-2018-producing-packages-3.png

We can click through our our EasyMath namespace and click on our Addition class to see phpDocumentor's summary and description of our code:

11-2018-producing-packages-4.png

If we click on Graphs and Class hierarchy diagram we see a diagram showing our class hierarchy:

11-2018-producing-packages-5.png

If we click on "Reports" and "Errors" we can see what phpDocumentor is flagging as a compilation error because we're missing summaries on our classes and our class files.

11-2018-producing-packages-6.png

Going back to our Addition class we can add a file summary and a class summary doc blocks as the first block after the PHP open tag.

src/Addition.php:

<?php
/**
 * \EasyMath\Addition Class
 */

namespace EasyMath;

/**
 * Class containing addition methods
 */
class Addition

src/Subtraction.php:

<?php
/**
 * \EasyMath\Subtraction Class
 */

namespace EasyMath;

/**
 * Class containing subtraction methods
 */
class Subtraction

Now we can run our command again to regenerate the documentation and we'll no longer see any errors when clicking on Reports and Errors.

Beyond Doc Blocks

While doc blocks are great for telling other developers and their code editors about your code it's also important to speak directly to developers about how to use your library. This starts with our README.md file. We should add instructions on how to require our library with Composer, what PHP versions we require, how to get help, and anything else we may find relevant to explain about our project. We can also add a fancy badge to be displayed on our repository to show our current build status.

We start with our library name and our Travis-CI badge. You can get your repositories badge by visiting your build and clicking on the build status badge. Since we're using Markdown on Github we'll select the Markdown option. Next we'll want to describe what our library does and why it is useful. We'll add the contents below to README.md

# PHP Easy Math

[![Build Status](https://travis-ci.org/svpernova09/php-easy-math.svg?branch=master)](https://travis-ci.org/svpernova09/php-easy-math)

## A simple library to do math for you

PHP Easy Math provides two classes containing two methods each. The Addition class provides the `add()` method which takes two parameters and returns the sum. The Addition class also contains the `sum()` method which will take any number of floats and return the sum. The Subtraction class provides a single `subtract()` class taking two parameters and will return the difference of the supplied parameters.

Now we'll want to instruct users how to include our library in their PHP project via Composer and how to use our code:

## Installation

Using [Composer](https://getcomposer.org/):

```
composer require svpernova/php-easy-math
```

## Usage

See [example.php](example.php)

Because we're including example.php which has usage examples of both classes our library contains we'll link to it from our README.md. If you want to paste your example code directly into the README.md file is perfectly fine as well.

example.php:

<?php

use EasyMath\Addition;
use EasyMath\Subtraction;

require __DIR__ . '/vendor/autoload.php';

$add = new Addition();
echo $add->add(3, 2) . PHP_EOL;

$sub = new Subtraction();
echo $sub->subtract(3, 2) . PHP_EOL;

Pull Requests and Issues

The last two things we need to add to our README.md are how to get help and how to contribute. While these two things are quite easy to say they are much harder to do. Do you really want pull requests? If not then leave the section off. There is nothing wrong with publishing code and never merging a pull request or helping anyone with issues they may have. "The Dude" from the movie "The Big Lebowski" said it best: "You're not wrong Walter. You're just an ***hole.". If this is your intent why did you even bother open sourcing your code? Reviewing PRs and listening to user feedback is part of the open source culture.

You're reading this magazine to learn how to be a better developer. Be a better developer by encouraging your users to ask for help and listening to users who contribute code back to your projects. Don't be an ***hole like the Walter character. We should all be good open source citizens and give back where we can. Showing your users you care about the issues they may run into and you care about others wanting to improve the project by submitting pull requests will go a long way to making your project successful.

Since we're hosting our library on GitHub, we want to use Github Issues to track any problems users may be having. While we do want to support pull requests and users contributing we should be up front about our PHP Easy Math library is for learning purposes so we may not merge all pull requests:

## Getting Help

Please open a new [Github issue](https://github.com/svpernova09/php-easy-math/issues/new) detailing your problem.

## Contributing

Pull requests welcome, however since this library was built for demonstration purposes only pull requests may not be merged in an effort to keep the library basic and easy to understand.

Now our README.md file is complete with information about what our library does, the build state, how to install, how to use it, how to contribute features or fixes, and where to get help.

Recap

This month we added a chunk of information to our README.md file to inform our potential users about our build status, installation instructions, usage, and how to contribute. Now that our library is ready for real world usage what happens when we get a pull request? What if we need to add features? Next month we're going to dive into how to triage issues, pull requests, adding features as well as tagging new releases!

Warning:

This post content may not be current, please double check the official documentation as needed.

This post may also be in an unedited form with grammatical or spelling mistakes, purchase the November 2018 issue from http://phparch.com for the professionally edited version.