Documenting groups of class constants with phpDocumentor - php

Let's say I've got a method that has a parameter, whose valid values are declared as class constants (think PGSQL_ASSOC/PGSQL_NUM/PGSQL_BOTH). And there's another method, with a similar parameter, using another set of class constants. Is there a way to describe to phpDocumentor that each set of constants as belonging to a logical group of alternatives? It would be useful to have them documented in groups, and being able to refer to the specific groups in the method documentation. Using docblock templates doesn't cut it, as the template's short description is ignored (adding useless clutter), while the long description of the template is appended to the constant-specific description, resulting in kind-of backwards wording (e.g. "BAR_MODE_1 does this and that. Operation modes for Foo::bar()", instead of "Operation modes for Foo::bar(): BAR_MODE_1 does this and that.").
Example:
class Foo {
// this group of constants are valid modes for the bar() method
const BAR_MODE_1 = 1;
const BAR_MODE_2 = 2;
const BAR_MODE_3 = 3;
/**
* #param int see Foo::BAR_MODE_* constants
*/
public function bar($mode) { ... }
// this group of constants are valid modes for the baz() method
const BAZ_MODE_1 = 1;
const BAZ_MODE_2 = 2;
const BAZ_MODE_3 = 3;
/**
* #param int see Foo::BAZ_MODE_* constants
*/
public function baz($mode) { ... }
}

Another style may be to use the PHPDocumentor DocBlock Templates
/**##+
* This comment applies to each in the block
*
* #var varType
*/
protected $_var1 = 1;
protected $_var2 = 2;
/**##-*/
see: http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html#basics.docblock

First thing which comes to my mind is the #see - Tag, it display a link to the documentation for an element.
/**
* #param int
* #see Foo::BAR_MODE_* constants
*/
public function bar($mode) { ... }
More details can be found here in the manual.

Related

PhpStorm: how to tell the var type of an array member?

I use PhpStorm 2016.2.1 IDE. I have a typed array (all members will be of the same, known class) and I'd like the IDE to know the type so I it can help me out with autocomplete/intellisense.
class MyClass{
/**
* #var array
*/
public $userArray;
public addUser($uid){ $this->$userArray[$uid] = new User($uid); }
public processUser($uid){
$oUser = $this->$userArray[$uid];
//since the PHP array can contain anything, the IDE makes
//no assumption about what data type $oUser is. How to let it
//know that it's of type User?
}
}
I have tried...
/**
* #var User
*/
public $oUser = ...;
And also
/**
* #type User
*/
public $oUser = ...;
So far, the only thing I've gotten to work is to use getter functions:
/**
* #return User
*/
function getUser($uid){ return $this->$userArray[$uid]; }
function processUser($uid){
//now the IDE knows the type of $oUser
$oUser = $this->getUser($uid);
}
But slowing down the script with unneeded function calls just to get better IDE support seems like a bad idea.
Any idea how I can let PhpStorm know the type of a variable? Or even better: how to tell it which type an array will contain in the PHPDoc metadata for that array?
For class variables, as you know, you can simply do
#var User
For local variables, it's not officially a supported format, but you must also specify the variable name:
#var User $oUser
Specific to PHPStorm, you'll need to use double asterisks (I think it's the only IDE that needs it, please consider that):
/** #var User $oUser */
See the PHPDoc manual for more info

Is there an equivalent of "let" vs. "var" in PHP?

I have recently started with learning Swift for iOS development. I have a background in scripting languages, especially PHP. Seeing that it is emphasized using let to define a constant in favor of var to have the compiler optimize the resulting code, I wondered: is there an equivalent for PHP? Or does it simply not apply as PHP is not statically compiled?
I tried my luck at searching but found no satisfying information on that point.
No, you can't have locally scoped constants in PHP. All PHP constants are always globally visible. There is also no concept like immutable/mutable variables.
You can implement immutable object members (PHP: immutable public member fields), but it's a different thing.
Actually there is a const keyword in the language, but the docs say:
Note:
As opposed to defining constants using define(), constants defined using the const keyword must be declared at the top-level scope because they are defined at compile-time. This means that they cannot be declared inside functions, loops, if statements or try/ catch blocks.
(from http://php.net/manual/en/language.constants.syntax.php)
Interpreted languages with a dynamic type systems can have something like the swift let statement, so this is not because swift is compiled and PHP is interpreted (for example, there is a javascript proposal to introduce that feature: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/const)
Is there an equivalent of “let” vs. “var” in PHP?
PHP doesn't have let as a native language feature, yet (as of current version 7.1.4 - 04/2017)
But, some high-performance extensions like Phalcon and Ice have support for let, because of the underlying usage of zephir-lang.
So, there is let, but indirectly; using the above mentioned extensions.
There are two use cases:
define a variable from a super global
define a variable in the local PHP symbol table, e.g.
// set variable $price in PHP
let name = "price";
let {name} = 10.2;
As an example take a look at the source for the Ice Router:
namespace Ice\Mvc\Route;
use Ice\Mvc\Route\Parser\ParserInterface;
use Ice\Mvc\Route\DataGenerator\DataGeneratorInterface;
use Ice\Mvc\Route\Parser\Std;
use Ice\Mvc\Route\DataGenerator\GroupCount as Generator;
class Collector
{
private routeParser { set };
private dataGenerator { set };
/**
* Constructs a route collector.
*
* #param RouteParser $routeParser
* #param DataGenerator $dataGenerator
*/
public function __construct(<ParserInterface> routeParser = null, <DataGeneratorInterface> dataGenerator = null)
{
if !routeParser {
let routeParser = new Std();
}
if !dataGenerator {
let dataGenerator = new Generator();
}
let this->routeParser = routeParser,
this->dataGenerator = dataGenerator;
}
/**
* Adds a route to the collection.
*
* The syntax used in the $route string depends on the used route parser.
*
* #param string|array $httpMethod
* #param string $route
* #param mixed $handler
*/
public function addRoute(var httpMethod, string route, handler = null)
{
var routeDatas, routeData, method;
let routeDatas = this->routeParser->parse(route);
if typeof httpMethod == "string" {
let method = httpMethod,
httpMethod = [method];
}
for method in httpMethod {
for routeData in routeDatas {
this->dataGenerator->addRoute(method, routeData, handler);
}
}
}
/**
* Returns the collected route data, as provided by the data generator.
*
* #return array
*/
public function getData()
{
return this->dataGenerator->getData();
}
}

how to check if field is autoincrement or not in symfony2 using doctrine2?

I am getting type of field using classMedataData using below,
$em->getClassMetadata('AcmeDemoBundle:' . $entityName)->getTypeOfField($fieldName)),
I want to check if the field is autoincrement or not. I tried using this,
$em->getClassMetadata('AcmeDemoBundle:' . $entityName)->isIdentifier($fieldName)),
but it doesnt give whether it is autoincrement or not ? Basically I want
generator: { strategy: AUTO }
metadata from entity name.
This information is stored in "generatorType" public MetadataInfo class property
To get it, use:
$em->getClassMetadata('AcmeDemoBundleBundle:'.$entityName)->generatorType;
generator_type constants are defined as is:
const GENERATOR_TYPE_AUTO = 1;
const GENERATOR_TYPE_SEQUENCE = 2;
const GENERATOR_TYPE_TABLE = 3;
const GENERATOR_TYPE_IDENTITY = 4;
const GENERATOR_TYPE_NONE = 5;
const GENERATOR_TYPE_UUID = 6;
const GENERATOR_TYPE_CUSTOM = 7;
Late-answering to #vishal's question, about what type to use for the auto-increment - the GENERATOR_TYPE_IDENTITY is actually the correct one (see below).
Excerpt from Symfony v3.3 code, ClassMetaDataInfo.php:
/* The Id generator types. */
/**
* AUTO means the generator type will depend on what the used platform prefers.
* Offers full portability.
*/
const GENERATOR_TYPE_AUTO = 1;
/**
* SEQUENCE means a separate sequence object will be used. Platforms that do
* not have native sequence support may emulate it. Full portability is currently
* not guaranteed.
*/
const GENERATOR_TYPE_SEQUENCE = 2;
/**
* TABLE means a separate table is used for id generation.
* Offers full portability.
*/
const GENERATOR_TYPE_TABLE = 3;
/**
* IDENTITY means an identity column is used for id generation. The database
* will fill in the id column on insertion. Platforms that do not support
* native identity columns may emulate them. Full portability is currently
* not guaranteed.
*/
const GENERATOR_TYPE_IDENTITY = 4;
/**
* NONE means the class does not have a generated id. That means the class
* must have a natural, manually assigned id.
*/
const GENERATOR_TYPE_NONE = 5;
/**
* UUID means that a UUID/GUID expression is used for id generation. Full
* portability is currently not guaranteed.
*/
const GENERATOR_TYPE_UUID = 6;
/**
* CUSTOM means that customer will use own ID generator that supposedly work
*/
const GENERATOR_TYPE_CUSTOM = 7;
So, you may use some function like this:
public function isPrimaryKeyAutoGenerated(): bool
{
return $this->classMetaData && $this->classMetaData->generatorType == ClassMetadataInfo::GENERATOR_TYPE_IDENTITY;
}

How to use phpDoc with overloaded methods?

Let's say I have a PHP class called Color, it's constructor accepts various params.
// hex color
$myColor = new Color('#FF008C');
// rgb channels
$myColor = new Color(253,15,82);
// array of rgb channels
$myColor = new Color(array(253,15,82));
// X11 color name
$myColor = new Color('lightGreen');
How should I use phpDoc to create API documentation for constructor and other methods like this?
How to use phpDoc with overloaded methods?
class Color {
/**
* Constructor
* what should be here?
*/
public function __construct() {
/* CODE */
}
}
Just my point of view, but you should not have multiple constructors in the first place - your constructor is going to be full of if/else-ladders, which really isn't a good idea, especially for something lightweight like a representation of a Color.
I strongly encourage you to try something like this instead:
class Color
{
protected function __construct($r, $g, $b)
{ ... }
public static function fromHex($hex) {
return new Color(...);
}
public static function fromRGB($r, $g, $b) { ... }
public static function fromArray(array $rgb) { ... }
...
}
Now, in consumer code, instead of somewhat mysterious and ambiguous constructor calls like these:
$a = new Color(0,0,0);
$b = new Color('#000000');
Instead you can have more legible and semantic consumer code, like this:
$a = Color::fromRGB(0,0,0);
$b = Color::fromHex('#000000');
This probably makes more sense to somebody reading the consumer code, it eliminates the logic required to make the ambiguous constructor work, and as a bonus (if you're using an IDE such as PhpStorm) you can have all your inspections pass. If you're running a documentation generator, this also ensures that all the options are documented individually, rather than lumped together in a verbal description.
Note that I declared the constructor protected - this is a personal preference, but if I'm going to have multiple static factory-methods, I prefer to see those consistently used in consumer code, rather than sometimes seeing Color::fromRGB(...) and other times new Color(...).
I think that is better to use #method annotation for class/interface, which declares overloading methods. This question is interesting for me too.
/**
* #method void setValue(int $value)
* #method void setValue(string $value)
* #method void setValue(string $value, int $startFrom)
*/
class Example
{
public function setValue($arg1, $arg2)
{
// ...
}
}
See http://phpdoc.org/docs/latest/references/phpdoc/tags/method.html
Because you allow variable length arguments there are two ways I would do this.
I would simply list the allowed arguments are parameters.
/**
* #param mixed $arg1 ... description
* #param mixed $arg2 ... description
* #param mixed $arg3 ... description
*/
public function __construct() {}
Or I would simply provide an explanation with some examples.
/**
* Explanation of different expected argument combinations.
*/
public function __construct() {}
Another alternative, since only one of the examples has more than one argument, would be to simply define the arguments in the method signature making the last 2 optional. Like this:
/**
* #param mixed $arg1 ...
* #param int $arg2 ...
* #param int $arg3 ...
*/
public function __construct($arg1, $arg2 = null, $arg3 = null) {}
I know of no elegant way to do this with phpDoc. The phpDoc comment/api formatting is based on a the Javadoc format. Javadoc doesn't have a feature set to support this because in java, if you want a method to have a variable number of arguments you re-declare the method prototype for each variation.
public double foo() {
}
public double foo(double my_param) {
}
So, my performance preference is to do something like
/**
* My General description
*
* Here explain what each argument combination can do
* #param mixed $arg1 can be array, string, hex as string, or int
* #param int $arg2 if arg1 is int, then this is etc, otherwise optional
* #param int $arg3 if ar1 is int, then this is etc, otherwise optional
*/
but this may not play nice with the various auto-documentation tools.
The according to Hoyle way to accomplish this can be found at the phpDoc site.

PHPDoc for variable-length arrays of arguments

Is there a syntax for documenting functions which take a single configuration array, rather than individual parameters?
I'm thinking specifically of CodeIgniter-style libraries, which use a mechanism similar to this:
<?php
//
// Library definition
//
class MyLibrary {
var $foo;
var $bar;
var $baz;
// ... and many more vars...
/* Following is how CodeIgniter documents their built-in libraries,
* which is mostly useless. AFAIK they should be specifying a name
* and description for their #param (which they don't) and omitting
* #return for constructors
*/
/**
* #access public
* #param array
* #return void
*/
function MyLibrary($config = array()) {
foreach ($config as $key => $value) {
$this->$key = $value;
}
}
}
//
// Library usage:
//
// Iniitialize our configuration parameters
$config['foo'] = 'test';
$config['bar'] = 4;
$config['baz'] = array('x', 'y', 'z');
$x = new MyLibrary($config);
?>
So my question is, is there some supprted way of documenting the configuration array beyond just the purely textual description? Actually specifying a proper #param [type] [name] [desc] that allows PHPDoc to parse out useful values?
As an aside, CodeIgniter really does just overwrite it's own values with those passed in via the $config array as above, effectively allowing you to clobber private members. I'm not a fan, but I'm stuck with it.
I've never seen any "good" way of documenting this -- and I've never seen anything that could be used by IDEs (such as Eclipse PDT) for parameters hinting either :-(
I would have said "do like your framework does", but as you said, what it does, here, is not quite good enough...
Maybe a quick/sort list of possible keys might be better than nothing, though ; a bit like this :
#param array $config [key1=>int, otherKey=>string]
Not sure how it would be interpreted by phpDocumentor or an IDE... But might be worth a try ?
This is, btw, one reason why I tend to avoid that kind of way of passing parameters -- at least when there are not too many (optional) parameters to a method.
The correct array #param notation for arrays is as specified in PHPlint
You can use it to document a config array in a useful manner:
Example:
/**
* Does stuff
*
* #param array[int|string]array[string]Object $config
*
* #return array[int]string
*/
public function foo(array $config)
{
// do stuff here
return array('foo', 'bar', 'baz');
}
You can do this:
/**
* #param array $param1
* #param string $param1['hello']
*/
function hey($param1)
{
}
and netbeans will pick it up but phpdoc messes up the documentation
I always use <pre> tags in situations like this. Ex.:
/**
* #param array $ops An array of options with the following keys:<pre>
* foo: (string) Some description...
* bar: (array) An array of bar data, with the following keys:
* boo: (string) ...
* far: (int) ...
* baz: (bool) ...
* </pre>
*/
Most IDEs and documentation generators I have used seem to render this in a reasonable way, though of course they don't provide any type checking or inspection of the array parameters.
There is currently no "official" (as in 'supported by multiple tools') way to do this.
The PHP FIG is discussing it at the moment at https://groups.google.com/d/topic/php-fig/o4ko1XsGtAw/discussion
A text description, to whatever degree of completeness you want, is really your only option. You can make it as legible as you want, but code analysis tools (phpDocumentor, IDE support) have no way to know how your $array is actually structured at runtime.
I agree with the many commenters that writing code this way exchanges coding convenience for code legibility.
I've used classes.
<?php
class MyLibrary {
var $foo;
var $bar;
var $baz;
/**
* #param MyLibraryConfig|null $config
*/
function MyLibrary( $config = null ) {
if ( isset( $config->foo ) ) {
$this->foo = $config->foo;
}
if ( isset( $config->baz ) ) {
$this->baz = $config->baz;
}
if ( isset( $config->bar ) ) {
$this->bar = $config->bar;
}
}
}
/**
* #property string $foo
* #property int $bar
* #property array $baz
*/
class MyLibraryConfig {
}
It works fairly well, main problem is that the code becomes littered with specific classes. They can be nested so parts of configuration can be reused.

Categories