duanqin9507 2014-07-03 01:51
浏览 45
已采纳

php注释,命名空间和使用关键字

I am writing an annotation parser for php (I cannot used any 3rd party ones due to specific needs) and I took sympfony2 code as an inspiration

namespace Acme\StoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */
class Product
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

As I can see here we define ORM in use statement and then somehow the annotation parser knows that ORM is an alias to Doctrine\ORM\Mapping.

My ultimate goal is to be able to pass class names as aliases into my annotations

use some/namespace/Enum;
use another/ns/PropEnum;

class Abc
{
   /**
    * @Enum(PropEnum)
    **/
   protected $prop;
}

Could you please point me towards the right direction as I do not even know where to start?

Thanks

展开全部

  • 写回答

1条回答 默认 最新

  • duandian8110 2014-07-03 03:27
    关注

    Let's take a look at how doctrine/annotations (the package used by Symfony) solves this problem.

    The PhpParser parses the PHP file of the class (which you can get by ReflectionClass#getFilename()). Let's look at the parseClass() method line by line:

    if (method_exists($class, 'getUseStatements')) {
        return $class->getUseStatements();
    }
    

    Doctrine has a custom StaticReflectionClass class which already has a getUseStatements() method to get the use statements in the class file. I assume you don't use that class, so let's move on!

    if (false === $filename = $class->getFilename()) {
        return array();
    }
    
    $content = $this->getFileContent($filename, $class->getStartLine());
    
    if (null === $content) {
        return array();
    }
    

    These statements retrieve the file content of the class. If there was no content or no file, there are also no use statements.

    $namespace = preg_quote($class->getNamespaceName());
    $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
    

    Here they are looking for the line that defines the namespace for the class in the file. It'll be followed by the use statements, so the regex just extracts the namespace and everything that follows it.

    $tokenizer = new TokenParser('<?php ' . $content);
    
    $statements = $tokenizer->parseUseStatements($class->getNamespaceName());
    
    return $statements;
    

    Then it creates a TokenParser class with only that content in it and let it find the use statements in it.

    If you look at the TokenParser, you'll find that it uses token_get_all() to transform the file into PHP tokens used by the PHP engine and then just moves through that token tree looking for T_USE statements, which it extracts and saves.

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部