├── .gitignore ├── .travis.yml ├── README.md ├── composer.json ├── phalcon.ini ├── phpunit.xml ├── src └── Enum │ ├── Adapter │ ├── AdapterInterface.php │ ├── PhalconAdapter.php │ └── ReflectionAdapter.php │ ├── Enum.php │ └── Exception │ └── EnumException.php └── tests ├── App ├── ErrorCode.php ├── ErrorCode2.php └── ErrorCodeNoPhalcon.php ├── Enum └── BaseTest.php ├── TestCase.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | 4 | *.cache -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | dist: trusty 4 | sudo: false 5 | 6 | php: 7 | - 7.0 8 | - 7.1 9 | - 7.2 10 | - 7.3 11 | - 7.4 12 | - nightly 13 | 14 | matrix: 15 | fast_finish: true 16 | allow_failures: 17 | - php: nightly 18 | 19 | git: 20 | depth: 1 21 | 22 | before_install: 23 | - export PHP_MAJOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 1)" 24 | - export PHP_MINOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 2)" 25 | - echo $PHP_MAJOR 26 | - echo $PHP_MINOR 27 | 28 | install: 29 | - cd $TRAVIS_BUILD_DIR 30 | # 更新扩展 31 | - sudo apt-get update 32 | - sudo apt-get install libpcre3-dev gcc make re2c 33 | # 安装Phalcon扩展 34 | - git clone https://github.com/phalcon/cphalcon.git --depth=1 35 | - cd $TRAVIS_BUILD_DIR/cphalcon/build 36 | - sudo ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config) 37 | - phpenv config-add $TRAVIS_BUILD_DIR/phalcon.ini 38 | # 安装项目 39 | - composer self-update 40 | - cd $TRAVIS_BUILD_DIR 41 | - composer install --prefer-dist --optimize-autoloader 42 | 43 | script: 44 | - cd $TRAVIS_BUILD_DIR 45 | - ./vendor/bin/phpunit 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # x-phalcon-enum 2 | 3 | [![Build Status](https://travis-ci.org/limingxinleo/x-phalcon-enum.svg?branch=master)](https://travis-ci.org/limingxinleo/x-phalcon-enum) 4 | 5 | ## 安装 6 | ~~~ 7 | composer require limingxinleo/x-phalcon-enum 8 | ~~~ 9 | 10 | ## 使用 11 | 定义枚举类 12 | ~~~ 13 | use Xin\Phalcon\Enum\Enum; 14 | 15 | class ErrorCode extends Enum 16 | { 17 | /** 18 | * @Message('非法的TOKEN') 19 | */ 20 | public static $ENUM_INVALID_TOKEN = 700; 21 | } 22 | ~~~ 23 | 24 | 25 | 26 | 27 | 获取单个枚举 28 | ~~~ 29 | $code = ErrorCode::$ENUM_INVALID_TOKEN; 30 | $message = ErrorCode::getMessage($code); 31 | ~~~ 32 | 33 | 获取枚举数组 34 | ~~~ 35 | 36 | $message = ErrorCode::toArray(); 37 | ~~~ 38 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "limingxinleo/x-phalcon-enum", 3 | "description": "a phalcon enum component", 4 | "type": "library", 5 | "license": "MIT", 6 | "keywords": [ 7 | "phalcon-enum", 8 | "phalcon-component", 9 | "phalcon" 10 | ], 11 | "authors": [ 12 | { 13 | "name": "李铭昕", 14 | "email": "715557344@qq.com" 15 | } 16 | ], 17 | "autoload": { 18 | "psr-4": { 19 | "Xin\\Phalcon\\": "src/" 20 | } 21 | }, 22 | "autoload-dev": { 23 | "psr-4": { 24 | "Tests\\": "tests/" 25 | } 26 | }, 27 | "require": { 28 | "php": ">=7.0", 29 | "limingxinleo/x-trait-common": "^1.1", 30 | "limingxinleo/support-str": "^1.0" 31 | }, 32 | "require-dev": { 33 | "phpunit/phpunit": ">=5.6" 34 | }, 35 | "suggest": { 36 | "php": ">=7.0", 37 | "ext-phalcon": "^3.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /phalcon.ini: -------------------------------------------------------------------------------- 1 | ; 2 | ; Phalcon Framework 3 | ; 4 | ; Copyright (c) 2011-present Phalcon Team (https://www.phalconphp.com) 5 | ; 6 | ; This source file is subject to the New BSD License that is bundled 7 | ; with this package in the file LICENSE.txt. 8 | ; 9 | ; If you did not receive a copy of the license and are unable to 10 | ; obtain it through the world-wide-web, please send an email 11 | ; to license@phalconphp.com so we can send you a copy immediately. 12 | 13 | [phalcon] 14 | extension=phalcon.so 15 | 16 | ; ----- Options to use the Phalcon Framework 17 | 18 | ; phalcon.db.escape_identifiers = On 19 | ; phalcon.db.force_casting = Off 20 | 21 | ; phalcon.orm.events = On 22 | ; phalcon.orm.virtual_foreign_keys = On 23 | ; phalcon.orm.column_renaming = On 24 | ; phalcon.orm.not_null_validations = On 25 | ; phalcon.orm.exception_on_failed_save = Off 26 | ; phalcon.orm.enable_literals = On 27 | ; phalcon.orm.late_state_binding = Off 28 | ; phalcon.orm.enable_implicit_joins = On 29 | ; phalcon.orm.cast_on_hydrate = Off 30 | ; phalcon.orm.ignore_unknown_columns = Off 31 | ; phalcon.orm.update_snapshot_on_save = On 32 | ; phalcon.orm.disable_assign_setters = Off 33 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | ./tests/ 14 | 15 | -------------------------------------------------------------------------------- /src/Enum/Adapter/AdapterInterface.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Xin\Phalcon\Enum\Adapter; 10 | 11 | interface AdapterInterface 12 | { 13 | public function __construct($class); 14 | 15 | public function getAnnotationsByName($name, $properties); 16 | } 17 | -------------------------------------------------------------------------------- /src/Enum/Adapter/PhalconAdapter.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Xin\Phalcon\Enum\Adapter; 10 | 11 | use Phalcon\Text; 12 | use Phalcon\Annotations\Adapter\Memory as MemoryAdapter; 13 | 14 | class PhalconAdapter implements AdapterInterface 15 | { 16 | protected $class; 17 | 18 | public function __construct($class) 19 | { 20 | $this->class = $class; 21 | } 22 | 23 | public function getAnnotationsByName($name, $properties) 24 | { 25 | $adapter = new MemoryAdapter(); 26 | $reflection = $adapter->get($this->class); 27 | $annotations = $reflection->getPropertiesAnnotations(); 28 | 29 | $result = []; 30 | foreach ($properties as $key => $val) { 31 | $isValid = Text::startsWith($key, 'ENUM_') // 必须以ENUM_开头 32 | && isset($annotations[$key]) // 当前字段存在注释 33 | && $annotations[$key]->has(Text::camelize($name)); // 当前字段存在此注解的注释 34 | 35 | if ($isValid) { 36 | // 获取对应注释 37 | $ret = $annotations[$key]->get(Text::camelize($name)); 38 | $result[$val] = $ret->getArgument(0); 39 | 40 | } 41 | } 42 | 43 | return $result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Enum/Adapter/ReflectionAdapter.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Xin\Phalcon\Enum\Adapter; 10 | 11 | use limx\Support\Str; 12 | use ReflectionClass; 13 | use ReflectionProperty; 14 | 15 | class ReflectionAdapter implements AdapterInterface 16 | { 17 | protected $class; 18 | 19 | public function __construct($class) 20 | { 21 | $this->class = $class; 22 | } 23 | 24 | public function getAnnotationsByName($name, $properties) 25 | { 26 | $result = []; 27 | foreach ($properties as $key => $val) { 28 | if (Str::startsWith($key, 'ENUM_')) { 29 | // 获取对应注释 30 | $ret = new ReflectionProperty($this->class, $key); 31 | $result[$val] = $this->getCommentByName($ret->getDocComment(), $name); 32 | } 33 | } 34 | 35 | return $result; 36 | } 37 | 38 | /** 39 | * @desc 根据name解析doc获取对应注释 40 | * @author limx 41 | * @param $doc 注释 42 | * @param $name 字段名 43 | */ 44 | protected function getCommentByName($doc, $name) 45 | { 46 | $name = Str::studly($name); 47 | $pattern = "/\@{$name}\(\'(.*)\'\)/U"; 48 | if (preg_match($pattern, $doc, $result)) { 49 | if (isset($result[1])) { 50 | return $result[1]; 51 | } 52 | } 53 | return null; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Enum/Enum.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Xin\Phalcon\Enum; 10 | 11 | use limx\Support\Str; 12 | use Xin\Phalcon\Enum\Adapter\AdapterInterface; 13 | use Xin\Phalcon\Enum\Adapter\PhalconAdapter; 14 | use Xin\Phalcon\Enum\Adapter\ReflectionAdapter; 15 | use Xin\Phalcon\Enum\Exception\EnumException; 16 | use ReflectionClass; 17 | use Xin\Traits\Common\InstanceTrait; 18 | 19 | /** 20 | * Class Enum 21 | * @package Xin\Phalcon\Enum 22 | * @method getMessage($code) 23 | * @method getDesc($code) 24 | */ 25 | abstract class Enum 26 | { 27 | use InstanceTrait; 28 | 29 | public static $_instance; 30 | 31 | /** @var AdapterInterface */ 32 | public $_adapter; 33 | 34 | protected $phalconExtEnable = true; 35 | 36 | private function __construct() 37 | { 38 | if ($this->phalconExtEnable && extension_loaded('phalcon')) { 39 | $this->_adapter = new PhalconAdapter(static::class); 40 | } else { 41 | $this->_adapter = new ReflectionAdapter(static::class); 42 | } 43 | } 44 | 45 | public function __call($name, $arguments) 46 | { 47 | if (!Str::startsWith($name, 'get')) { 48 | throw new EnumException('The function is not defined!'); 49 | } 50 | if (!isset($arguments) || count($arguments) === 0) { 51 | throw new EnumException('The Code is required'); 52 | } 53 | 54 | $code = $arguments[0]; 55 | $name = strtolower(substr($name, 3)); 56 | 57 | if (isset($this->$name)) { 58 | return isset($this->$name[$code]) ? $this->$name[$code] : ''; 59 | } 60 | 61 | // 获取变量 62 | $ref = new ReflectionClass(static::class); 63 | $properties = $ref->getDefaultProperties(); 64 | 65 | $arr = $this->_adapter->getAnnotationsByName($name, $properties); 66 | 67 | if (version_compare(PHP_VERSION, 7, '<')) { 68 | // 版本小于7 69 | return isset($arr[$code]) ? $arr[$code] : ''; 70 | } 71 | 72 | $this->$name = $arr; 73 | return isset($this->$name[$code]) ? $this->$name[$code] : ''; 74 | } 75 | 76 | public static function __callStatic($method, $arguments) 77 | { 78 | return static::getInstance()->$method(...$arguments); 79 | } 80 | 81 | /** 82 | * 获取枚举数组 83 | * @return array 84 | */ 85 | public static function toArray(){ 86 | 87 | $ref = new ReflectionClass(static::class); 88 | $properties = $ref->getDefaultProperties(); 89 | $_adapter = new ReflectionAdapter(static::class); 90 | $arr = $_adapter->getAnnotationsByName('Message', $properties); 91 | 92 | return $arr; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Enum/Exception/EnumException.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Xin\Phalcon\Enum\Exception; 10 | 11 | use Exception; 12 | 13 | class EnumException extends Exception 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /tests/App/ErrorCode.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Tests\App; 10 | 11 | use Xin\Phalcon\Enum\Enum; 12 | 13 | class ErrorCode extends Enum 14 | { 15 | /** 16 | * @Message('非法的TOKEN') 17 | * @Desc('需要重新登录') 18 | */ 19 | public static $ENUM_INVALID_TOKEN = 700; 20 | 21 | /** 22 | * @Message('Code不为数字') 23 | */ 24 | public static $ENUM_NOT_NUMBER = 'OP1000'; 25 | } 26 | -------------------------------------------------------------------------------- /tests/App/ErrorCode2.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Tests\App; 10 | 11 | use Xin\Phalcon\Enum\Enum; 12 | 13 | class ErrorCode2 extends Enum 14 | { 15 | /** 16 | * @Message('非法的TOKEN 2') 17 | * @Desc('需要重新登录') 18 | */ 19 | public static $ENUM_INVALID_TOKEN = 700; 20 | } 21 | -------------------------------------------------------------------------------- /tests/App/ErrorCodeNoPhalcon.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Tests\App; 10 | 11 | use Xin\Phalcon\Enum\Enum; 12 | 13 | class ErrorCodeNoPhalcon extends Enum 14 | { 15 | protected $phalconExtEnable = false; 16 | 17 | /** 18 | * @Message('非法的TOKEN') 19 | * @Desc('需要重新登录') 20 | */ 21 | public static $ENUM_INVALID_TOKEN = 700; 22 | } 23 | -------------------------------------------------------------------------------- /tests/Enum/BaseTest.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Tests\Middleware; 10 | 11 | use Tests\App\ErrorCode; 12 | use Tests\App\ErrorCode2; 13 | use Tests\App\ErrorCodeNoPhalcon; 14 | use Tests\TestCase; 15 | 16 | class BaseTest extends TestCase 17 | { 18 | public function testCode() 19 | { 20 | $this->assertEquals(700, ErrorCode::$ENUM_INVALID_TOKEN); 21 | } 22 | 23 | public function testMessage() 24 | { 25 | $this->assertEquals('非法的TOKEN', ErrorCode::getMessage(ErrorCode::$ENUM_INVALID_TOKEN)); 26 | } 27 | 28 | public function testDesc() 29 | { 30 | $this->assertEquals('需要重新登录', ErrorCode::getDesc(ErrorCode::$ENUM_INVALID_TOKEN)); 31 | } 32 | 33 | public function testTwoEnum() 34 | { 35 | $code = ErrorCode::$ENUM_INVALID_TOKEN; 36 | $msg1 = ErrorCode2::getMessage($code); 37 | $msg2 = ErrorCode::getMessage($code); 38 | 39 | $this->assertEquals('非法的TOKEN', $msg2); 40 | $this->assertEquals('非法的TOKEN 2', $msg1); 41 | } 42 | 43 | public function testNoPhalconExt() 44 | { 45 | $code = ErrorCode::$ENUM_INVALID_TOKEN; 46 | $res = ErrorCodeNoPhalcon::getMessage($code); 47 | $res2 = ErrorCode::getMessage($code); 48 | $this->assertEquals($res, $res2); 49 | 50 | $res = ErrorCodeNoPhalcon::getDesc($code); 51 | $res2 = ErrorCode::getDesc($code); 52 | $this->assertEquals($res, $res2); 53 | 54 | $res3 = ErrorCodeNoPhalcon::getMsg($code); 55 | $this->assertEquals('', $res3); 56 | } 57 | 58 | public function testNotNumber() 59 | { 60 | $code = ErrorCode::$ENUM_NOT_NUMBER; 61 | $res = ErrorCode::getMessage($code); 62 | 63 | $this->assertEquals('Code不为数字', $res); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | namespace Tests; 10 | 11 | use Phalcon\Di\FactoryDefault; 12 | use PHPUnit\Framework\TestCase as UnitTestCase; 13 | use Phalcon\Config; 14 | use Xin\Phalcon\Middleware\Manager; 15 | use Xin\Phalcon\Middleware\Mvc\Dispatcher; 16 | 17 | class TestCase extends UnitTestCase 18 | { 19 | public $di; 20 | 21 | /** @var Dispatcher $dispatcher */ 22 | public $dispatcher; 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 8 | // +---------------------------------------------------------------------- 9 | require __DIR__ . '/../vendor/autoload.php'; 10 | define('TESTS_PATH', __DIR__); 11 | --------------------------------------------------------------------------------