How to Find Annotations in a PHP5 Object

How to find annotations in a PHP5 object?

You can do this using ReflectionClass::getDocComment, example:

function getClassAnnotations($class)
{
$r = new ReflectionClass($class);
$doc = $r->getDocComment();
preg_match_all('#@(.*?)\n#s', $doc, $annotations);
return $annotations[1];
}

Live demo: http://codepad.viper-7.com/u8bFT4

Getting annotation of comment in PHP, I get too an email of comment

In an email address the @ is always just close other characters, while in the real annotations it's always preceded by at least one space.

So you might merely change your regex to reflect that:

    preg_match_all('# @(.*?)\n#s', $docComment, $annotations);

and it'll work fine without anything else, since in your function you're already trim()ing the annotation... which was useless till now :)

Mark class field

To go forward with reflection API you should "mark" your fields with "appropriate"(formatted) comment.
Here is working solution using ReflectionClass class, ReflectionProperty::getDocComment, ReflectionProperty::getName and ReflectionProperty::getValue methods:

class A {

public $field1;
public $field2;

/**
* @dont_serialize
*/
public $field3;

}

$obj = new A();
$obj->field1 = "important data";
$obj->field2 = "needed data";
$obj->field3 = "not important data";

function MySerialize($obj) {
$reflector = new ReflectionClass(get_class($obj));
$props = $reflector->getProperties();
$new_arr = [];

foreach ($props as $property) {
if (strpos($property->getDocComment(), "@dont_serialize") === false) {
$new_arr[$property->getName()] = $property->getValue($obj);
}
}
return serialize($new_arr);
}

print_r(MySerialize($obj));

The output:

"a:2:{s:6:"field1";s:14:"important data";s:6:"field2";s:11:"needed data";}"

What are The Valid & Readable approaches to Commenting in PHP5?

Quoting the Manual on Comments:

PHP supports 'C', 'C++' and Unix shell-style (Perl style) comments. For example:

<?php
echo 'This is a test'; // This is a one-line c++ style comment
/* This is a multi line comment
yet another line of comment */
echo 'This is yet another test';
echo 'One Final Test'; # This is a one-line shell-style comment
?>

In general, you will want to avoid using comments in your sourcecode. To quote Martin Fowler:

When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous.

which means something like

// check if date is in Summer period
if ($date->after(DATE::SUMMER_START) && $date->before(DATE::SUMMER_END)) {

should be rewritten to

if ($date->isInSummerPeriod()) { …

Another comment type you will sometimes encounter is the separator comment, e.g. something like

// --------------------------------------------

or

################################################

Those are usually indicative that the code they are used in is doing too much. If you find this in a class, check the responsibility of the class and see if some parts of it are better refactored into a standalone class.

As for API docs, the common notation is PHPDoc, e.g.

/**
* Short Desc
*
* Long Desc
*
* @param type $name description
* @return type description
*/
public function methodName($name) { …

I would argue that you can omit Short and Long Desc if the remaining method signature clearly communicates what it does. However, that requires a certain discipline and knowledge in how to actually write Clean Code. For instance, the following is totally superfluous:

/**
* Get the timestamp property
*
* The method returns the {@link $timestamp} property as an integer.
*
* @return integer the timestamp
*/
public function getTimestamp() { …

and should be shortened to

/**
* @return integer
*/
public function getTimestamp() { …

Needless to say, whether you go for full API docs or not also depends on the project. I'd expect any framework I can download and use to have full API docs. The important thing is just that whatever you decide to do, do it consistently.

PHP: The Reflection API - Great Addition To PHP With Little Use

Reflection is definitely here to stay. You may use it, but keep in mind it is said to be slow and overkill for simple UseCases. Using one of the functions in the Classes/Objects function package is often the faster alternative.

A UseCase where Reflection comes in handy is when parsing for annotations in the DocBlock of a class. For instance, PHPUnit uses the annotations @test to tell the PHPUnit TestRunner that it should consider a method a test. The @covers annotation will help it collect Code Coverage data. The FLOW3 framework makes use of Annotations for their AOP framework.

Unfortunately, some of the newer additions to PHP > 5.3, are not documented yet that much. Just look at the SPL. Same thing. That doesn't mean you cannot use it though. The Reflection API is very expressive and easy to figure out from the method names. And Google often has blog posts about how to use certain extensions. For the Reflection API, check out:

  • http://www.phpriot.com/articles/reflection-api
  • http://mark-story.com/posts/view/using-the-php-reflection-api-for-fun-and-profit
  • http://www.tuxradar.com/practicalphp/16/4/0
  • http://weierophinney.net/matthew/archives/125-PHP-5s-Reflection-API.html

and for SPL

  • http://www.phpro.org/tutorials/Introduction-to-SPL.html

Something cool I just discovered recently. As of 5.1.2, you can invoke the Reflection API from the command line too:

$php --rf strtotime
Function [ <internal:date> function strtotime ] {

- Parameters [2] {
Parameter #0 [ <required> $time ]
Parameter #1 [ <optional> $now ]
}
}

Type hinting in PHP 7 - array of objects

It's not included.

If it's not included, do you have Any clue why it was not included when type hinting was added?

With the current array implementation, it would require checking all array elements at runtime, because the array itself contains no type information.

It has actually already been proposed for PHP 5.6 but rejected: RFC "arrayof" - interestingly not because of performance issues which turned out to be neglible, but because there was no agreement in how exactly it should be implemented. There was also the objection that it is incomplete without scalar type hints. If you are interested in the whole discussion, read it in the mailing list archive.

IMHO array type hints would provide most benefit together with typed arrays, and I'd love to see them implemented.

So maybe it's about time for a new RFC and to reopen this discussion.


Partial Workaround:

you can type hint variadic arguments and thus write the signature as

function findUserByAge(int $age, User ...$users) : array

Usage:

findUserByAge(15, ...$userInput);

In this call, the argument $userInput will be "unpacked" into single variables, and in the method itself "packed" back into an array $users. Each item is validated to be of type User. $userInput can also be an iterator, it will be converted to an array.

Unfortunately there is no similar workaround for return types, and you can only use it for the last argument.



Related Topics



Leave a reply



Submit