├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── docs
└── README.md
├── phpunit.xml.dist
├── sami.doc.inc
├── src
├── autoload.php
├── collection
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.md
│ ├── composer.json
│ ├── phpunit.xml.dist
│ ├── src
│ │ ├── ActiveData.php
│ │ ├── Collection.php
│ │ ├── CollectionInterface.php
│ │ ├── Configuration.php
│ │ ├── JsonMessage.php
│ │ ├── Language.php
│ │ ├── LiteCollection.php
│ │ └── SimpleCollection.php
│ └── test
│ │ ├── LanguageTest.php
│ │ ├── boot.php
│ │ └── testdata
│ │ ├── en
│ │ └── response.php
│ │ └── zh-CN
│ │ └── response.php
├── data-parser
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.md
│ ├── composer.json
│ ├── phpunit.xml.dist
│ ├── src
│ │ ├── AbstractDataParser.php
│ │ ├── DataParserAwareTrait.php
│ │ ├── DataParserInterface.php
│ │ ├── JsonParser.php
│ │ ├── MsgPackParser.php
│ │ ├── PhpParser.php
│ │ └── SwooleParser.php
│ └── test
│ │ ├── JsonParserTest.php
│ │ ├── PhpParserTest.php
│ │ └── boot.php
├── dev-helper
│ └── Console
│ │ └── DevController.php
├── di
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.md
│ ├── composer.json
│ ├── example
│ │ └── di.php
│ ├── phpunit.xml.dist
│ ├── src
│ │ ├── CallableResolver.php
│ │ ├── CallableResolverAwareTrait.php
│ │ ├── Container.php
│ │ ├── DIManager.php
│ │ ├── Exception
│ │ │ ├── DependencyResolutionException.php
│ │ │ └── NotFoundException.php
│ │ ├── NameAliasTrait.php
│ │ ├── ObjectItem.php
│ │ └── ServiceProviderInterface.php
│ └── test
│ │ ├── ContainerTest.php
│ │ ├── MakeByMethod.php
│ │ ├── MakeByStatic.php
│ │ ├── SomeClass.php
│ │ └── boot.php
└── helper-utils
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.md
│ ├── composer.json
│ ├── phpunit.xml.dist
│ ├── src
│ ├── Helper
│ │ ├── AssertHelper.php
│ │ ├── DataHelper.php
│ │ ├── DateHelper.php
│ │ ├── DsnHelper.php
│ │ ├── FormatHelper.php
│ │ ├── Http.php
│ │ ├── IntHelper.php
│ │ ├── SslHelper.php
│ │ └── UtilHelper.php
│ ├── Traits
│ │ ├── AopProxyAwareTrait.php
│ │ ├── Config
│ │ │ ├── ConfigTrait.php
│ │ │ ├── LiteConfigTrait.php
│ │ │ ├── LiteOptionsTrait.php
│ │ │ └── OptionsTrait.php
│ │ ├── Event
│ │ │ ├── EventTrait.php
│ │ │ ├── FixedEventStaticTrait.php
│ │ │ ├── FixedEventTrait.php
│ │ │ ├── LiteEventStaticTrait.php
│ │ │ └── LiteEventTrait.php
│ │ ├── LiteContainerStaticTrait.php
│ │ ├── LiteContainerTrait.php
│ │ ├── LogProfileTrait.php
│ │ ├── LogShortTrait.php
│ │ ├── NameAliasStaticTrait.php
│ │ ├── NameAliasTrait.php
│ │ ├── PathAliasTrait.php
│ │ ├── PathResolverTrait.php
│ │ └── RuntimeProfileTrait.php
│ └── Util
│ │ ├── AopProxy.php
│ │ ├── DataProxy.php
│ │ ├── DataResult.php
│ │ ├── DeferredCallable.php
│ │ ├── Pipeline.php
│ │ └── PipelineInterface.php
│ └── test
│ └── boot.php
├── test
└── boot.php
└── toolkit
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | # 对所有文件生效
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 4
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | # 对后缀名为 md 的文件生效
13 | [*.md]
14 | trim_trailing_whitespace = false
15 |
16 | [*.xml|*.xml.dist]
17 | indent_size = 2
18 |
19 | [*.json]
20 | indent_size = 2
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .phpintel/
3 | caches/
4 | vendor/
5 | !README.md
6 | !.gitkeep
7 | composer.lock
8 | *.swp
9 | *.log
10 | *.pid
11 | *.patch
12 | *.cache
13 | .DS_Store
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 inhere
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP工具包
2 |
3 | [](https://packagist.org/packages/toolkit/str-utils)
4 |
5 | php的一些有用的基础工具库实现和收集整理。
6 |
7 | > 本仓库是主仓库,开发后推送到各个组件仓库。如果只需要一个或部分工具,可以单独配置require
8 |
9 | **1. 字符串工具**
10 |
11 | 常用的字符串操作帮助工具类库,以及一些 html,json 编解码, token,url 等工具类
12 |
13 | - 独立包名 [toolkit/str-utils](https://github.com/php-toolkit/str-utils)
14 | - 在本仓库的 [libs/str-utils](libs/str-utils)
15 |
16 | **2. 数组工具**
17 |
18 | 常用的数组操作帮助工具类库
19 |
20 | - 独立包名 [toolkit/arr-utils](https://github.com/php-toolkit/arr-utils)
21 | - 在本仓库的 [libs/arr-utils](libs/arr-utils)
22 |
23 | **3. 对象工具**
24 |
25 | 常用的对象操作帮助工具类、traits库
26 |
27 | - 独立包名 [toolkit/obj-utils](https://github.com/php-toolkit/obj-utils)
28 | - 在本仓库的 [libs/obj-utils](libs/obj-utils)
29 |
30 | **4. 系统工具**
31 |
32 | 常用的系统操作帮助工具类库。系统环境信息,执行命令,简单的进程操作使用类(fork,run,stop,wait ...)等
33 |
34 | - 独立包名 [toolkit/sys-utils](https://github.com/php-toolkit/sys-utils)
35 | - 在本仓库的 [libs/sys-utils](libs/sys-utils)
36 |
37 | **5. php工具**
38 |
39 | 常用的php操作帮助工具类库。php环境信息,数据打印,`.env`加载,简单的autoload类等
40 |
41 | - 独立包名 [toolkit/php-utils](https://github.com/php-toolkit/php-utils)
42 | - 在本仓库的 [libs/php-utils](libs/php-utils)
43 |
44 | **6. 文件系统工具**
45 |
46 | 常用的文件系统操作帮助工具类库。文件查找,创建,判断,信息获取,内容读取等,目录的创建,权限,拷贝,删除等。
47 |
48 | - 独立包名 [toolkit/file-utils](https://github.com/php-toolkit/file-utils)
49 | - 在本仓库的 [libs/file-utils](libs/file-utils)
50 |
51 | **7. CLI工具**
52 |
53 | 常用的php cli环境的帮助工具类库。cli下的内容输出,读取。丰富的颜色内容输出,cli下的php文件高亮,简单的光标操作。
54 |
55 | - 独立包名 [toolkit/cli-utils](https://github.com/php-toolkit/cli-utils)
56 | - 在本仓库的 [libs/cli-utils](libs/cli-utils)
57 |
58 | **8. 数据收集器**
59 |
60 | 数据收集器 `Collection` 实现。可用于配置数据管理、数据收集、数据迭代等。
61 |
62 | - 独立包名 [toolkit/collection](https://github.com/php-toolkit/collection)
63 | - 在本仓库的 [libs/collection](libs/collection)
64 |
65 | **9. 简单的DI容器实现**
66 |
67 | 简单的 `psr/container` 对象管理容器实现
68 |
69 | - 独立包名 [toolkit/di](https://github.com/php-toolkit/di)
70 | - 在本仓库的 [libs/di](libs/di)
71 |
72 | **10. 数据解析器**
73 |
74 | 数据解析器。`json` `php` `swoole` `msgpack` 格式的数据解析的简单封装。
75 |
76 | - 独立包名 [toolkit/data-parser](https://github.com/php-toolkit/data-parser)
77 | - 在本仓库的 [libs/data-parser](libs/data-parser)
78 |
79 | **11. 额外的帮助类库**
80 |
81 | 额外的帮助类库。数据、日期、格式化等帮助类。 简单的 config,options,event,alias等traits收集整理
82 |
83 | - 独立包名 [toolkit/helper-utils](https://github.com/php-toolkit/helper-utils)
84 | - 在本仓库的 [libs/helper-utils](libs/helper-utils)
85 |
86 | ## 安装
87 |
88 | ```bash
89 | composer require toolkit/toolkit
90 | ```
91 |
92 | ## 文档
93 |
94 | - classes docs https://php-toolkit.github.io/toolkit/classes-docs/master/
95 |
96 | ## 开发
97 |
98 | ```bash
99 | composer install
100 | php toolkit dev -h
101 | ```
102 |
103 | ### git subtree
104 |
105 | git subtree usage example:
106 |
107 | - add a lib repo
108 |
109 | ```bash
110 | git subtree add --prefix=libs/php-utils https://github.com/php-toolkit/php-utils master --squash
111 | ```
112 |
113 | - update a lib repo
114 |
115 | ```bash
116 | git subtree pull --prefix=libs/php-utils https://github.com/php-toolkit/php-utils master --squash
117 | ```
118 |
119 | - push a lib repo
120 |
121 | ```bash
122 | git subtree push --prefix=libs/php-utils https://github.com/php-toolkit/php-utils master
123 | ```
124 |
125 | ## License
126 |
127 | MIT
128 |
129 | ## 我的其他项目
130 |
131 | - **`inhere/console`** 功能丰富的命令行应用,命令行工具库
132 | - git repo [github](https://github.com/inhere/php-console) [gitee](https://gitee.com/inhere/php-console)
133 | - **`inhere/php-validate`** 一个简洁小巧且功能完善的php验证库。仅有几个文件,无依赖。
134 | - git repo [github](https://github.com/inhere/php-validate) [gitee](https://gitee.com/inhere/php-validate)
135 | - **`inhere/sroute`** 轻量且快速的路由库
136 | - git repo [github](https://github.com/inhere/php-srouter) [gitee](https://gitee.com/inhere/php-srouter)
137 | - **`inhere/event-manager`** psr-14 的事件管理实现
138 | - git repo [github](https://github.com/inhere/php-event-manager) [gitee](https://gitee.com/inhere/php-event-manager)
139 | - **`inhere/middleware`** psr-15 HTTP中间件的实现
140 | - git repo [github](https://github.com/inhere/php-middleware) [gitee](https://gitee.com/inhere/php-middleware)
141 |
142 |
143 | > 更多请查看我的 [github](https://github.com/inhere)
144 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toolkit/toolkit",
3 | "type": "library",
4 | "keywords": [
5 | "php",
6 | "library",
7 | "tools"
8 | ],
9 | "homepage": "https://github.com/php-toolkit/toolkit",
10 | "description": "some useful library of the php",
11 | "license": "MIT",
12 | "authors": [
13 | {
14 | "name": "inhere",
15 | "email": "in.798@qq.com",
16 | "homepage": "http://www.yzone.net/"
17 | }
18 | ],
19 | "require": {
20 | "php": ">7.1.0",
21 | "psr/container": "^1.0",
22 | "toolkit/stdlib": "^1.0"
23 | },
24 | "require-dev": {
25 | "inhere/console": "dev-master"
26 | },
27 | "autoload": {
28 | "psr-4": {
29 | "Toolkit\\Dev\\": "src/"
30 | }
31 | },
32 | "suggest": {
33 | "inhere/php-validate": "Very lightweight data validate tool",
34 | "inhere/console": "a lightweight php console application library."
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # toolkit
2 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | libs/*/test
15 |
16 |
17 |
18 |
19 |
20 | libs/*/src
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/sami.doc.inc:
--------------------------------------------------------------------------------
1 | files()
9 | ->name('*.php')
10 | ->notName('routes.php')
11 | ->exclude(['test', 'example'])
12 | ->in([
13 | __DIR__ . '/libs/'
14 | ]);
15 |
16 | $versions = GitVersionCollection::create(__DIR__);
17 |
18 | return new Sami($iterator, [
19 | // 'theme' => 'enhanced',
20 | // 'versions' => $versions,
21 | 'title' => 'Php Toolkit Classes Documentation',
22 | 'build_dir' => __DIR__ . '/classes-docs/%version%',
23 | 'cache_dir' => __DIR__ . '/caches/%version%',
24 | 'default_opened_level' => 1,
25 | // 'store' => new MyArrayStore,
26 | ]);
27 |
28 | /**
29 | * usage: php sami.phar update --force sami.doc.inc
30 | */
31 |
--------------------------------------------------------------------------------
/src/autoload.php:
--------------------------------------------------------------------------------
1 | $lib . '/arr-utils/src',
7 | 'Toolkit\ArrUtilTest\\' => $lib . '/arr-utils/test',
8 | // cli-utils
9 | 'Toolkit\Cli\\' => $lib . '/cli-utils/src',
10 | 'Toolkit\CliTest\\' => $lib . '/cli-utils/test',
11 | // di
12 | 'Toolkit\DI\\' => $lib . '/di/src',
13 | 'Toolkit\DITest\\' => $lib . '/di/test',
14 | // collection
15 | 'Toolkit\CollectionTest\\' => $lib . '/collection/test',
16 | 'Toolkit\Collection\\' => $lib . '/collection/src',
17 | // file parse
18 | 'Toolkit\File\Parse\\' => $lib . '/file-parse/src',
19 | 'Toolkit\File\ParseTest\\' => $lib . '/file-parse/test',
20 | // file utils
21 | 'Toolkit\File\\' => $lib . '/file-utils/src',
22 | 'Toolkit\FileTest\\' => $lib . '/file-utils/test',
23 | // obj-utils
24 | 'Toolkit\ObjUtil\\' => $lib . '/obj-utils/src',
25 | 'Toolkit\ObjUtilTest\\' => $lib . '/obj-utils/test',
26 | // php utils
27 | 'Toolkit\PhpUtil\\' => $lib . '/php-utils/src',
28 | 'Toolkit\PhpUtilTest\\' => $lib . '/php-utils/test',
29 | // str utils
30 | 'Toolkit\StrUtil\\' => $lib . '/str-utils/src',
31 | 'Toolkit\StrUtilTest\\' => $lib . '/str-utils/test',
32 | // sys utils
33 | 'Toolkit\Sys\\' => $lib . '/sys-utils/src',
34 | 'Toolkit\SysTest\\' => $lib . '/sys-utils/test',
35 | ];
36 |
37 | spl_autoload_register(function ($class) use ($map) {
38 | foreach ($map as $np => $dir) {
39 | if (0 === strpos($class, $np)) {
40 | $path = str_replace('\\', '/', substr($class, strlen($np)));
41 | $file = $dir . "/example/{$path}.php";
42 |
43 | if ($file && is_file($file)) {
44 | include $file;
45 | return;
46 | }
47 | }
48 | }
49 | });
50 |
--------------------------------------------------------------------------------
/src/collection/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .phpintel/
3 | !README.md
4 | !.gitkeep
5 | composer.lock
6 | *.swp
7 | *.log
8 | *.pid
9 | *.patch
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/src/collection/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 inhere
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/src/collection/README.md:
--------------------------------------------------------------------------------
1 | # data collection
2 |
3 | [](LICENSE)
4 | [](https://packagist.org/packages/toolkit/collection)
5 | [](https://packagist.org/packages/toolkit/collection)
6 |
7 | data collection utils for php
8 |
9 | - data collection
10 | - language manage
11 |
12 | ## Install
13 |
14 | ```bash
15 | composer require toolkit/collection
16 | ```
17 |
18 | ## License
19 |
20 | MIT
21 |
--------------------------------------------------------------------------------
/src/collection/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toolkit/collection",
3 | "type": "library",
4 | "description": "some data collection tool library of the php",
5 | "keywords": [
6 | "library",
7 | "tool",
8 | "php"
9 | ],
10 | "homepage": "https://github.com/php-toolkit/collection",
11 | "license": "MIT",
12 | "authors": [
13 | {
14 | "name": "inhere",
15 | "email": "in.798@qq.com",
16 | "homepage": "http://www.yzone.net/"
17 | }
18 | ],
19 | "require": {
20 | "php": ">7.1.0",
21 | "toolkit/arr-utils": "~1.0",
22 | "toolkit/str-utils": "~1.0",
23 | "toolkit/obj-utils": "~1.0",
24 | "toolkit/file-parse": "~1.0"
25 | },
26 | "autoload": {
27 | "psr-4": {
28 | "Toolkit\\Collection\\": "src/"
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/collection/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | test/
15 |
16 |
17 |
18 |
19 |
20 | src
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/collection/src/ActiveData.php:
--------------------------------------------------------------------------------
1 | load($data, $recursive);
54 | }
55 | }
56 |
57 | /**
58 | * 初始化,载入数据
59 | *
60 | * @param array $data
61 | * @param bool $recursive
62 | *
63 | * @return $this
64 | */
65 | public function load($data, bool $recursive = false): self
66 | {
67 | foreach ($data as $name => $value) {
68 | $name = trim($name);
69 |
70 | if (is_numeric($name)) {
71 | continue;
72 | }
73 |
74 | $this->$name = $recursive && is_array($value) ? static::create($value, $recursive) : $value;
75 | }
76 |
77 | return $this;
78 | }
79 |
80 | public function isStrict(): bool
81 | {
82 | return false;
83 | }
84 |
85 | /**
86 | * @param bool $toArray
87 | *
88 | * @return array|ArrayIterator
89 | * @throws ReflectionException
90 | */
91 | public function all(bool $toArray = false)
92 | {
93 | $class = new ReflectionClass($this);
94 | $attrs = [];
95 |
96 | foreach ($class->getProperties() as $property) {
97 | if ($property->isPublic() && !$property->isStatic()) {
98 | $attrs[$property->getName()] = $property->getValue($this);
99 | }
100 | }
101 |
102 | //return $toArray ? $attrs : (new \ArrayObject($attrs));
103 | return $toArray ? $attrs : new ArrayIterator($attrs);
104 | }
105 |
106 | /**
107 | * 以点连接 快速获取子级节点的值
108 | *
109 | * @param string $name
110 | *
111 | * @return ActiveData|mixed
112 | */
113 | public function get(string $name)
114 | {
115 | if (strpos($name, '.')) {
116 | $names = explode('.', $name);
117 | $node = $this;
118 |
119 | foreach ($names as $n) {
120 | if ($node instanceof self && property_exists($node, $n)) {
121 | $node = $node->$n;
122 | } else {
123 | if ($this->isStrict()) {
124 | throw new RuntimeException("Stored data don't exists node '$n'");
125 | }
126 |
127 | $node = null;
128 | break;
129 | }
130 | }
131 |
132 | return $node;
133 | }
134 |
135 | return property_exists($this, $name) ? $this->$name : null;
136 | }
137 |
138 | /**
139 | * Defined by IteratorAggregate interface
140 | * Returns an iterator for this object, for use with foreach
141 | *
142 | * @return ArrayIterator
143 | * @throws ReflectionException
144 | */
145 | public function getIterator(): ArrayIterator
146 | {
147 | return $this->all();
148 | }
149 |
150 | /**
151 | * Checks whether an offset exists in the iterator.
152 | *
153 | * @param mixed $offset The array offset.
154 | *
155 | * @return boolean True if the offset exists, false otherwise.
156 | */
157 | public function offsetExists($offset): bool
158 | {
159 | return property_exists($this, $offset);
160 | }
161 |
162 | /**
163 | * Gets an offset in the iterator.
164 | *
165 | * @param mixed $offset The array offset.
166 | *
167 | * @return mixed The array value if it exists, null otherwise.
168 | */
169 | public function offsetGet($offset)
170 | {
171 | return $this->$offset;
172 | }
173 |
174 | /**
175 | * Sets an offset in the iterator.
176 | *
177 | * @param mixed $offset The array offset.
178 | * @param mixed $value The array value.
179 | *
180 | * @return void
181 | */
182 | public function offsetSet($offset, $value): void
183 | {
184 | $this->$offset = $value;
185 | }
186 |
187 | /**
188 | * Unset an offset in the iterator.
189 | *
190 | * @param mixed $offset The array offset.
191 | *
192 | * @return void
193 | */
194 | public function offsetUnset($offset): void
195 | {
196 | unset($this->$offset);
197 | }
198 |
199 | public function __isset($name)
200 | {
201 | return $this->offsetExists($name);
202 | }
203 |
204 | public function __set($name, $value)
205 | {
206 | }
207 |
208 | public function __get($name)
209 | {
210 | return $this->get($name);
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/src/collection/src/CollectionInterface.php:
--------------------------------------------------------------------------------
1 | format = $format;
73 |
74 | if (is_string($data) && is_dir($data)) {
75 | $this->mode = self::MODE_FOLDER;
76 | $this->folderPath = $data;
77 | $data = null;
78 | }
79 |
80 | if ($this->mode === self::MODE_FOLDER && !is_dir($this->folderPath)) {
81 | throw new InvalidArgumentException("Config mode is 'folder'. the property 'folderPath' must is a folder path!");
82 | }
83 |
84 | parent::__construct($data, $this->format, $name);
85 | }
86 |
87 | /**
88 | * set config value by path
89 | *
90 | * @param string $path
91 | * @param mixed $value
92 | *
93 | * @return mixed
94 | * @throws InvalidArgumentException
95 | */
96 | public function set($path, $value)
97 | {
98 | // if is readonly
99 | if ($this->readonly && $this->has($path)) {
100 | throw new InvalidArgumentException("Config data have been setting readonly. don't allow change.");
101 | }
102 |
103 | return parent::set($path, $value);
104 | }
105 |
106 | /**
107 | * get value by path
108 | *
109 | * @param string $path
110 | * @param string $default
111 | *
112 | * @return mixed
113 | * @throws InvalidArgumentException
114 | */
115 | public function get(string $path, $default = null)
116 | {
117 | if ($this->mode === self::MODE_FOLDER) {
118 | $nodes = Str::toArray($path, $this->separator);
119 | $name = array_shift($nodes);// config file name
120 |
121 | // if config file not load. load it.
122 | if (!isset($this->data[$name])) {
123 | $file = $this->folderPath . "/{$name}.{$this->format}";
124 |
125 | if (!is_file($file)) {
126 | throw new InvalidArgumentException("The want get config file not exist, Name: $name, File: $file");
127 | }
128 |
129 | $this->data[$name] = self::read($file, $this->format);
130 | }
131 | }
132 |
133 | return parent::get($path, $default);
134 | }
135 |
136 | /**
137 | * get Mode
138 | *
139 | * @return string
140 | */
141 | public function getMode(): string
142 | {
143 | return $this->mode;
144 | }
145 |
146 | /**
147 | * @param string $mode
148 | */
149 | public function setMode(string $mode): void
150 | {
151 | $this->mode = $mode;
152 | }
153 |
154 | /**
155 | * @param bool $readonly
156 | */
157 | public function setReadonly($readonly): void
158 | {
159 | $this->readonly = (bool)$readonly;
160 | }
161 |
162 | /**
163 | * data is Readonly
164 | *
165 | * @return boolean
166 | */
167 | public function isReadonly(): bool
168 | {
169 | return $this->readonly;
170 | }
171 |
172 | /**
173 | * @return string
174 | */
175 | public function getFormat(): string
176 | {
177 | return $this->format;
178 | }
179 |
180 | /**
181 | * @param string $format
182 | */
183 | public function setFormat(string $format): void
184 | {
185 | $this->format = $format;
186 | }
187 |
188 | /**
189 | * @return string
190 | */
191 | public function getFolderPath(): string
192 | {
193 | return $this->folderPath;
194 | }
195 |
196 | /**
197 | * @param string $folderPath
198 | *
199 | * @throws InvalidArgumentException
200 | */
201 | public function setFolderPath(string $folderPath): void
202 | {
203 | if (!is_dir($folderPath)) {
204 | throw new InvalidArgumentException("The config files folder path is not exists! Path: $folderPath");
205 | }
206 |
207 | $this->folderPath = $folderPath;
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/src/collection/src/JsonMessage.php:
--------------------------------------------------------------------------------
1 | 'success', 'code' => 23]);
19 | * $mg->data = [ 'key' => 'test'];
20 | * echo json_encode($mg);
21 | * response to client:
22 | * {
23 | * "code":23,
24 | * "msg":"success",
25 | * "data": {
26 | * "key":"value"
27 | * }
28 | * }
29 | */
30 | class JsonMessage
31 | {
32 | /**
33 | * @var int
34 | */
35 | public $code;
36 |
37 | /**
38 | * @var string
39 | */
40 | public $msg;
41 |
42 | /**
43 | * @var int|float
44 | */
45 | public $time;
46 |
47 | /**
48 | * @var array|string
49 | */
50 | public $data;
51 |
52 | public static function make($data = null, $msg = 'success', $code = 0)
53 | {
54 | return new static($data, $msg, $code);
55 | }
56 |
57 | /**
58 | * JsonMessage constructor.
59 | *
60 | * @param null $data
61 | * @param string $msg
62 | * @param int $code
63 | */
64 | public function __construct($data = null, $msg = 'success', $code = 0)
65 | {
66 | $this->data = $data;
67 | $this->msg = $msg;
68 | $this->code = $code;
69 | }
70 |
71 | /**
72 | * @return bool
73 | */
74 | public function isSuccess(): bool
75 | {
76 | return (int)$this->code === 0;
77 | }
78 |
79 | /**
80 | * @return bool
81 | */
82 | public function isFailure(): bool
83 | {
84 | return (int)$this->code !== 0;
85 | }
86 |
87 | /**
88 | * @param $code
89 | *
90 | * @return $this
91 | */
92 | public function code($code): self
93 | {
94 | $this->code = (int)$code;
95 |
96 | return $this;
97 | }
98 |
99 | /**
100 | * @param $msg
101 | *
102 | * @return $this
103 | */
104 | public function msg($msg): self
105 | {
106 | $this->msg = $msg;
107 |
108 | return $this;
109 | }
110 |
111 | /**
112 | * @param string $key
113 | * @param mixed $value
114 | */
115 | public function add($key, $value): void
116 | {
117 | if (null === $this->data) {
118 | $this->data = [];
119 | }
120 |
121 | $this->data[$key] = $value;
122 | }
123 |
124 | /**
125 | * @param array|string $data
126 | *
127 | * @return $this
128 | */
129 | public function data($data): self
130 | {
131 | $this->data = $data;
132 |
133 | return $this;
134 | }
135 |
136 | /**
137 | * @return array
138 | */
139 | public function all(): array
140 | {
141 | // add a new alert message
142 | return [
143 | 'code' => (int)$this->code,
144 | 'msg' => $this->msg,
145 | 'data' => (array)$this->data
146 | ];
147 | }
148 |
149 | /**
150 | * @return array
151 | */
152 | public function toArray(): array
153 | {
154 | return $this->all();
155 | }
156 |
157 | /**
158 | * @return string
159 | */
160 | public function __toString()
161 | {
162 | return (string)json_encode($this->all());
163 | }
164 |
165 | /**
166 | * @param string $name
167 | *
168 | * @return bool
169 | */
170 | public function __isset(string $name)
171 | {
172 | return isset($this->data[$name]);
173 | }
174 |
175 | /**
176 | * @param string $name
177 | * @param $value
178 | */
179 | public function __set(string $name, $value)
180 | {
181 | $this->data[$name] = $value;
182 | }
183 |
184 | /**
185 | * @param string $name
186 | *
187 | * @return mixed
188 | * @throws InvalidArgumentException
189 | */
190 | public function __get($name)
191 | {
192 | if (isset($this->data[$name])) {
193 | return $this->data[$name];
194 | }
195 |
196 | throw new InvalidArgumentException(sprintf('the property is not exists: %s', $name));
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/src/collection/src/LiteCollection.php:
--------------------------------------------------------------------------------
1 | replace($items);
41 | }
42 |
43 | /**
44 | * @param string $name
45 | * @param null|mixed $default
46 | *
47 | * @return mixed|null
48 | */
49 | public function get(string $name, $default = null)
50 | {
51 | return $this[$name] ?? $default;
52 | }
53 |
54 | /**
55 | * @param string $name
56 | * @param mixed $value
57 | *
58 | * @return mixed|null
59 | */
60 | public function add($name, $value)
61 | {
62 | if (isset($this[$name])) {
63 | return null;
64 | }
65 |
66 | $this[$name] = $value;
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * @param string $name
73 | * @param mixed $value
74 | *
75 | * @return mixed|null
76 | */
77 | public function set($name, $value)
78 | {
79 | return $this[$name] = $value;
80 | }
81 |
82 | /**
83 | * @param array $items
84 | */
85 | public function replace(array $items)
86 | {
87 | foreach ($items as $key => $value) {
88 | $this->set($key, $value);
89 | }
90 | }
91 |
92 | /**
93 | * @param callable $filter
94 | *
95 | * @return static
96 | */
97 | public function reject(callable $filter)
98 | {
99 | $data = [];
100 |
101 | foreach ($this as $key => $value) {
102 | if (!$filter($value, $key)) {
103 | $data[$key] = $value;
104 | }
105 |
106 | unset($this[$key]);
107 | }
108 |
109 | return new static($data);
110 | }
111 |
112 | /**
113 | * @param callable $callback
114 | *
115 | * @return static
116 | */
117 | public function map(callable $callback)
118 | {
119 | $data = [];
120 |
121 | foreach ($this as $key => $value) {
122 | $data[$key] = $callback($value, $key);
123 | unset($this[$key]);
124 | }
125 |
126 | return new static($data);
127 | }
128 |
129 | /**
130 | * @param string $char
131 | *
132 | * @return string
133 | */
134 | public function implode($char = ','): string
135 | {
136 | // $string = '';
137 | //
138 | // foreach ($this as $key => $value) {
139 | // $string .= is_array($value) ? $this->implode($char, $value) : implode($char, $value);
140 | // $string .= implode($char, $value);
141 | // }
142 |
143 | return implode($char, $this->all());
144 | }
145 |
146 | /**
147 | * {@inheritDoc}
148 | */
149 | public function all(): array
150 | {
151 | return $this->getArrayCopy();
152 | }
153 |
154 | /**
155 | * {@inheritDoc}
156 | */
157 | public function has(string $key): bool
158 | {
159 | return array_key_exists($key, $this->data);
160 | }
161 |
162 | /**
163 | * {@inheritDoc}
164 | */
165 | public function remove($key)
166 | {
167 | if (isset($this[$key])) {
168 | $val = $this[$key];
169 | unset($this[$key]);
170 |
171 | return $val;
172 | }
173 |
174 | return null;
175 | }
176 |
177 | /**
178 | * clear all data
179 | */
180 | public function clear(): void
181 | {
182 | foreach ($this as $key) {
183 | unset($this[$key]);
184 | }
185 | }
186 |
187 | /**
188 | * Specify data which should be serialized to JSON
189 | *
190 | * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
191 | * @return mixed data which can be serialized by json_encode,
192 | * which is a value of any type other than a resource.
193 | * @since 5.4.0
194 | */
195 | public function jsonSerialize()
196 | {
197 | return $this->getArrayCopy();
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/collection/src/SimpleCollection.php:
--------------------------------------------------------------------------------
1 | replace($items);
42 | }
43 |
44 | public function __destruct()
45 | {
46 | $this->clear();
47 | }
48 |
49 | /********************************************************************************
50 | * Collection interface
51 | *******************************************************************************/
52 |
53 | /**
54 | * Set collection item
55 | *
56 | * @param string $key The data key
57 | * @param mixed $value The data value
58 | *
59 | * @return $this
60 | */
61 | public function set($key, $value)
62 | {
63 | $this->data[$key] = $value;
64 |
65 | return $this;
66 | }
67 |
68 | /**
69 | * @param $name
70 | * @param $value
71 | *
72 | * @return $this
73 | */
74 | public function add($name, $value): self
75 | {
76 | if (!$this->has($name)) {
77 | $this->set($name, $value);
78 | }
79 |
80 | return $this;
81 | }
82 |
83 | /**
84 | * Get collection item for key
85 | *
86 | * @param string $key The data key
87 | * @param mixed $default The default value to return if data key does not exist
88 | *
89 | * @return mixed The key's value, or the default value
90 | */
91 | public function get(string $key, $default = null)
92 | {
93 | return $this->has($key) ? $this->data[$key] : $default;
94 | }
95 |
96 | /**
97 | * Add item to collection
98 | *
99 | * @param array $items Key-value array of data to append to this collection
100 | */
101 | public function replace(array $items)
102 | {
103 | foreach ($items as $key => $value) {
104 | $this->set($key, $value);
105 | }
106 | }
107 |
108 | /**
109 | * @param array $names
110 | *
111 | * @return array
112 | */
113 | public function gets(array $names): array
114 | {
115 | $values = [];
116 |
117 | foreach ($names as $name) {
118 | $values[] = $this->get($name);
119 | }
120 |
121 | return $values;
122 | }
123 |
124 | /**
125 | * @param array $data
126 | *
127 | * @return static
128 | */
129 | public function sets(array $data)
130 | {
131 | foreach ($data as $key => $value) {
132 | $this->set($key, $value);
133 | }
134 |
135 | return $this;
136 | }
137 |
138 | /**
139 | * @param callable $filter
140 | *
141 | * @return static
142 | */
143 | public function reject(callable $filter)
144 | {
145 | $data = [];
146 |
147 | foreach ($this as $key => $value) {
148 | if (!$filter($value, $key)) {
149 | $data[$key] = $value;
150 | }
151 |
152 | unset($this[$key]);
153 | }
154 |
155 | return new static($data);
156 | }
157 |
158 | /**
159 | * @param callable $callback
160 | *
161 | * @return static
162 | */
163 | public function map(callable $callback)
164 | {
165 | $data = [];
166 |
167 | foreach ($this->getIterator() as $key => $value) {
168 | $data[$key] = $callback($value, $key);
169 | unset($this[$key]);
170 | }
171 |
172 | return new static($data);
173 | }
174 |
175 | /**
176 | * @param string $char
177 | *
178 | * @return string
179 | */
180 | public function implode(string $char = ','): string
181 | {
182 | return implode($char, $this->all());
183 | }
184 |
185 | /**
186 | * Get all items in collection
187 | *
188 | * @return array The collection's source data
189 | */
190 | public function all(): array
191 | {
192 | return $this->data;
193 | }
194 |
195 | /**
196 | * @return array
197 | */
198 | public function toArray(): array
199 | {
200 | return $this->all();
201 | }
202 |
203 | /**
204 | * Get collection keys
205 | *
206 | * @return array The collection's source data keys
207 | */
208 | public function keys(): array
209 | {
210 | return array_keys($this->data);
211 | }
212 |
213 | /**
214 | * Does this collection have a given key?
215 | *
216 | * @param string $key The data key
217 | *
218 | * @return bool
219 | */
220 | public function has(string $key): bool
221 | {
222 | return array_key_exists($key, $this->data);
223 | }
224 |
225 | /**
226 | * Remove item from collection
227 | *
228 | * @param string $key The data key
229 | *
230 | * @return mixed|null
231 | */
232 | public function remove($key)
233 | {
234 | $value = null;
235 |
236 | if ($this->has($key)) {
237 | $value = $this->data[$key];
238 | unset($this->data[$key]);
239 | }
240 |
241 | return $value;
242 | }
243 |
244 | /**
245 | * Remove all items from collection
246 | */
247 | public function clear(): void
248 | {
249 | $this->data = [];
250 | }
251 |
252 | /********************************************************************************
253 | * ArrayAccess interface
254 | *******************************************************************************/
255 |
256 | /**
257 | * Does this collection have a given key?
258 | *
259 | * @param string $key The data key
260 | *
261 | * @return bool
262 | */
263 | public function offsetExists($key): bool
264 | {
265 | return $this->has($key);
266 | }
267 |
268 | /**
269 | * Get collection item for key
270 | *
271 | * @param string $key The data key
272 | *
273 | * @return mixed The key's value, or the default value
274 | */
275 | public function offsetGet($key)
276 | {
277 | return $this->get($key);
278 | }
279 |
280 | /**
281 | * Set collection item
282 | *
283 | * @param string $key The data key
284 | * @param mixed $value The data value
285 | */
286 | public function offsetSet($key, $value)
287 | {
288 | $this->set($key, $value);
289 | }
290 |
291 | /**
292 | * Remove item from collection
293 | *
294 | * @param string $key The data key
295 | *
296 | * @return mixed|null
297 | */
298 | public function offsetUnset($key)
299 | {
300 | return $this->remove($key);
301 | }
302 |
303 | /********************************************************************************
304 | * Countable interface
305 | *******************************************************************************/
306 |
307 | /**
308 | * Get number of items in collection
309 | *
310 | * @return int
311 | */
312 | public function count(): int
313 | {
314 | return count($this->data);
315 | }
316 |
317 | /********************************************************************************
318 | * JsonSerializable interface
319 | *******************************************************************************/
320 |
321 | /**
322 | * @return array
323 | */
324 | public function jsonSerialize(): array
325 | {
326 | return $this->data;
327 | }
328 |
329 | /********************************************************************************
330 | * Serializable interface
331 | *******************************************************************************/
332 |
333 | /**
334 | * @return string
335 | */
336 | public function serialize(): string
337 | {
338 | return serialize($this->data);
339 | }
340 |
341 | /**
342 | * @param string $serialized
343 | * @param bool|array $allowedClasses
344 | */
345 | public function unserialize($serialized, $allowedClasses = false)
346 | {
347 | $this->data = unserialize($serialized, ['allowed_classes' => $allowedClasses]);
348 | }
349 |
350 | /********************************************************************************
351 | * IteratorAggregate interface
352 | *******************************************************************************/
353 |
354 | /**
355 | * Get collection iterator
356 | *
357 | * @return ArrayIterator
358 | */
359 | public function getIterator(): Traversable
360 | {
361 | return new ArrayIterator($this->data);
362 | }
363 |
364 | /********************************************************************************
365 | * Magic method
366 | ******************************************************************************/
367 |
368 | /**
369 | * @param $name
370 | *
371 | * @return mixed
372 | */
373 | public function __get($name)
374 | {
375 | return $this->get($name);
376 | }
377 |
378 | public function __set($name, $value)
379 | {
380 | return $this->set($name, $value);
381 | }
382 |
383 | public function __isset($name)
384 | {
385 | return $this->has($name);
386 | }
387 | }
388 |
--------------------------------------------------------------------------------
/src/collection/test/LanguageTest.php:
--------------------------------------------------------------------------------
1 | 'en',
27 | 'allowed' => ['en', 'zh-CN'],
28 | 'basePath' => __DIR__ . '/testdata',
29 | 'langFiles' => [
30 | 'response.php'
31 | ],
32 | ]);
33 |
34 | $arr = [
35 | 0 => 'a',
36 | 1 => 'b',
37 | 'k' => 'c',
38 | ];
39 |
40 |
41 | $msg = $l->tl('response.key');
42 | $this->assertEquals('message', $msg);
43 | $this->assertTrue($l->has('response.key'));
44 | $this->assertEquals('successful', $l->trans('response.0'));
45 | $this->assertEquals('error', $l->trans('response.2'));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/collection/test/boot.php:
--------------------------------------------------------------------------------
1 | 'successful',
11 | 2 => 'error',
12 | 'key' => 'message',
13 | ];
14 |
--------------------------------------------------------------------------------
/src/collection/test/testdata/zh-CN/response.php:
--------------------------------------------------------------------------------
1 | '操作成功',
12 | 2 => '发生错误',
13 | 'key' => '消息',
14 | ];
15 |
--------------------------------------------------------------------------------
/src/data-parser/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .phpintel/
3 | !README.md
4 | !.gitkeep
5 | composer.lock
6 | *.swp
7 | *.log
8 | *.pid
9 | *.patch
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/src/data-parser/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 inhere
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/src/data-parser/README.md:
--------------------------------------------------------------------------------
1 | # data parser utils
2 |
3 | simple data parser for php
4 |
5 | driver
6 |
7 | - json(by `json_encode`)
8 | - php(by `serialize`)
9 | - swoole(by extension `swoole_serialize`)
10 | - msgpack(by extension `msgpack`)
11 |
12 | ## Install
13 |
14 | - composer command
15 |
16 | ```bash
17 | composer require toolkit/data-parser
18 | ```
19 |
20 | ## Usage
21 |
22 | ```php
23 | $parser = new SwooleParser();
24 | // $parser = new JsonParser();
25 | // $parser = new PhpParser();
26 | // $parser = new MsgPackParser();
27 |
28 | // encode
29 | $encoded = $parser->encode($data);
30 |
31 | // decode
32 | $decoded = $parser->encode($encoded);
33 | ```
34 |
35 | ## Unit testing
36 |
37 | ```bash
38 | phpunit
39 | ```
40 |
41 | ## License
42 |
43 | MIT
44 |
--------------------------------------------------------------------------------
/src/data-parser/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toolkit/data-parser",
3 | "type": "library",
4 | "description": "some data parser tool library of the php",
5 | "keywords": [
6 | "library",
7 | "tool",
8 | "php"
9 | ],
10 | "homepage": "https://github.com/php-toolkit/data-parser",
11 | "license": "MIT",
12 | "authors": [
13 | {
14 | "name": "inhere",
15 | "email": "in.798@qq.com",
16 | "homepage": "http://www.yzone.net/"
17 | }
18 | ],
19 | "require": {
20 | "php": ">7.1.0"
21 | },
22 | "autoload": {
23 | "psr-4": {
24 | "Toolkit\\DataParser\\": "src/"
25 | }
26 | },
27 | "suggest": {
28 | "inhere/php-validate": "Very lightweight data validate tool",
29 | "inhere/console": "a lightweight php console application library."
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/data-parser/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 | test/
16 |
17 |
18 |
19 |
20 |
21 | src
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/data-parser/src/AbstractDataParser.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | abstract class AbstractDataParser implements DataParserInterface
18 | {
19 | /**
20 | * @var array
21 | */
22 | protected $encodeOpts;
23 |
24 | /**
25 | * @var array
26 | */
27 | protected $decodeOpts;
28 |
29 | /**
30 | * JsonParser constructor.
31 | *
32 | * @param array $encodeOpts
33 | * @param array $decodeOpts
34 | */
35 | public function __construct(array $encodeOpts = [], array $decodeOpts = [])
36 | {
37 | $this->encodeOpts = $encodeOpts;
38 | $this->decodeOpts = $decodeOpts;
39 | }
40 |
41 | /**
42 | * @return array
43 | */
44 | public function getEncodeOpts(): array
45 | {
46 | return $this->encodeOpts;
47 | }
48 |
49 | /**
50 | * @return array
51 | */
52 | public function getDecodeOpts(): array
53 | {
54 | return $this->decodeOpts;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/data-parser/src/DataParserAwareTrait.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | trait DataParserAwareTrait
18 | {
19 | /**
20 | * @var DataParserInterface
21 | */
22 | private $parser;
23 |
24 | /**
25 | * @return DataParserInterface
26 | */
27 | public function getParser(): DataParserInterface
28 | {
29 | if (!$this->parser) {
30 | $this->parser = new PhpParser();
31 | }
32 |
33 | return $this->parser;
34 | }
35 |
36 | /**
37 | * @param DataParserInterface $parser
38 | *
39 | * @return DataParserAwareTrait
40 | */
41 | public function setParser(DataParserInterface $parser): self
42 | {
43 | $this->parser = $parser;
44 |
45 | return $this;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/data-parser/src/DataParserInterface.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | interface DataParserInterface
18 | {
19 | /**
20 | * @param mixed $data
21 | *
22 | * @return string
23 | */
24 | public function encode($data): string;
25 |
26 | /**
27 | * @param string $data
28 | *
29 | * @return mixed
30 | */
31 | public function decode(string $data);
32 | }
33 |
--------------------------------------------------------------------------------
/src/data-parser/src/JsonParser.php:
--------------------------------------------------------------------------------
1 |
19 | */
20 | class JsonParser extends AbstractDataParser
21 | {
22 | /**
23 | * class constructor.
24 | *
25 | * @param array $encodeOpts
26 | * @param array $decodeOpts
27 | */
28 | public function __construct(array $encodeOpts = [], array $decodeOpts = [])
29 | {
30 | parent::__construct($encodeOpts, $decodeOpts ?: [true]);
31 | }
32 |
33 | /**
34 | * @param mixed $data
35 | *
36 | * @return string
37 | */
38 | public function encode($data): string
39 | {
40 | return json_encode($data, ...$this->encodeOpts);
41 | }
42 |
43 | /**
44 | * @param string $data
45 | *
46 | * @return mixed
47 | */
48 | public function decode(string $data)
49 | {
50 | return json_decode($data, ...$this->decodeOpts);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/data-parser/src/MsgPackParser.php:
--------------------------------------------------------------------------------
1 |
21 | * @link https://github.com/msgpack/msgpack-php php-ext
22 | * @link https://github.com/rybakit/msgpack.php php
23 | */
24 | class MsgPackParser extends AbstractDataParser
25 | {
26 | /**
27 | * class constructor.
28 | *
29 | * @throws RuntimeException
30 | */
31 | public function __construct()
32 | {
33 | if (!function_exists('msgpack_pack')) {
34 | throw new RuntimeException("The php extension 'msgpack' is required!");
35 | }
36 |
37 | parent::__construct();
38 | }
39 |
40 | /**
41 | * @param mixed $data
42 | *
43 | * @return string
44 | */
45 | public function encode($data): string
46 | {
47 | return msgpack_pack($data);
48 | }
49 |
50 | /**
51 | * @param string $data
52 | *
53 | * @return mixed
54 | */
55 | public function decode(string $data)
56 | {
57 | return msgpack_unpack($data);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/data-parser/src/PhpParser.php:
--------------------------------------------------------------------------------
1 |
19 | */
20 | class PhpParser implements DataParserInterface
21 | {
22 | /**
23 | * @param mixed $data
24 | *
25 | * @return string
26 | */
27 | public function encode($data): string
28 | {
29 | return serialize($data);
30 | }
31 |
32 | /**
33 | * @param string $data
34 | *
35 | * @return mixed
36 | */
37 | public function decode(string $data)
38 | {
39 | return unserialize($data, ['allowed_classes' => false]);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/data-parser/src/SwooleParser.php:
--------------------------------------------------------------------------------
1 |
20 | * @link https://wiki.swoole.com/wiki/page/p-serialize.html
21 | */
22 | class SwooleParser extends AbstractDataParser
23 | {
24 | /**
25 | * class constructor.
26 | *
27 | * @param array $encodeOpts
28 | *
29 | * @throws RuntimeException
30 | */
31 | public function __construct(array $encodeOpts = [])
32 | {
33 | if (!class_exists(Serialize::class, false)) {
34 | throw new RuntimeException("The php extension 'swoole_serialize' is required!");
35 | }
36 |
37 | parent::__construct($encodeOpts);
38 | }
39 |
40 | /**
41 | * @param mixed $data
42 | *
43 | * @return string
44 | */
45 | public function encode($data): string
46 | {
47 | return (string)Serialize::pack($data, ...$this->encodeOpts);
48 | }
49 |
50 | /**
51 | * @param string $data
52 | *
53 | * @return mixed
54 | */
55 | public function decode(string $data)
56 | {
57 | return Serialize::unpack($data, ...$this->decodeOpts);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/data-parser/test/JsonParserTest.php:
--------------------------------------------------------------------------------
1 | decode($str);
27 |
28 | $this->assertArrayHasKey('name', $ret);
29 | }
30 |
31 | public function testEncode(): void
32 | {
33 | $data = [
34 | 'name' => 'value',
35 | ];
36 |
37 | $parser = new JsonParser();
38 | $ret = $parser->encode($data);
39 |
40 | $this->assertJson($ret);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/data-parser/test/PhpParserTest.php:
--------------------------------------------------------------------------------
1 | decode($str);
27 |
28 | $this->assertIsArray($ret);
29 | $this->assertArrayHasKey('name', $ret);
30 | }
31 |
32 | public function testEncode(): void
33 | {
34 | $data = [
35 | 'name' => 'value',
36 | ];
37 |
38 | $parser = new PhpParser();
39 | $ret = $parser->encode($data);
40 |
41 | $this->assertIsString($ret);
42 | $this->assertStringStartsWith('a:1:{', $ret);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/data-parser/test/boot.php:
--------------------------------------------------------------------------------
1 | 'className',
39 | // 2. 类的静态方法, 参数($definition[0])则传入对应方法 className::staticMethod(args...)
40 | 'class' => 'className::staticMethod',
41 | // 3. 类的动态方法, 参数($definition[0]) 则传入对应方法 (new className)->method(args...)
42 | 'class' => 'className->method',
43 |
44 | // 设置参数方式, 没有key
45 | [
46 | arg1,arg2,arg3,...
47 | ]
48 |
49 | // 设置属性 , // prop1 prop2 prop3 将会被收集 作为属性
50 | prop1 => value1,
51 | prop2 => value2,
52 | ... ...
53 |
54 | // 一些服务设置(别名,是否共享). 将会合并到最后一个参数中
55 | '_options' => [...]
56 | ]
57 | ```
58 |
59 | - object:
60 |
61 | ```php
62 | $definition = new xxClass();
63 | ```
64 |
65 | - closure:
66 |
67 | ```php
68 | $definition = function($di){
69 | return object;
70 | };
71 | ```
72 |
73 | #### 选项
74 |
75 | - array `$opts` 选项
76 |
77 | ```php
78 | [
79 | 'shared' => (bool), 是否共享,单例
80 | 'locked' => (bool), 是否锁定服务
81 | 'aliases' => (array), 别名
82 | 'init' => (bool), 立即初始化
83 | ]
84 | ```
85 |
86 | ## License
87 |
88 | MIT
89 |
--------------------------------------------------------------------------------
/src/di/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toolkit/di",
3 | "type": "library",
4 | "description": "some di tool library of the php",
5 | "keywords": [
6 | "library",
7 | "tool",
8 | "php"
9 | ],
10 | "homepage": "https://github.com/php-toolkit/di",
11 | "license": "MIT",
12 | "authors": [
13 | {
14 | "name": "inhere",
15 | "email": "in.798@qq.com",
16 | "homepage": "http://www.yzone.net/"
17 | }
18 | ],
19 | "require": {
20 | "php": ">7.1.0",
21 | "toolkit/obj-utils": "^1.0",
22 | "psr/container": "^1.0"
23 | },
24 | "autoload": {
25 | "psr-4": {
26 | "Toolkit\\DI\\": "src/"
27 | }
28 | },
29 | "suggest": {
30 | "inhere/php-validate": "Very lightweight data validate tool",
31 | "inhere/console": "a lightweight php console application library."
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/di/example/di.php:
--------------------------------------------------------------------------------
1 | LiteLogger::make(['name' => 'test']),
16 | 'logger2' => [
17 | 'target' => LiteLogger::class . '::make',
18 | ['name' => 'test2']// first arg
19 | ]
20 | ]);
21 |
22 | var_dump($di);
23 |
24 | var_dump($di->get('logger2'));
25 |
--------------------------------------------------------------------------------
/src/di/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | test/
15 |
16 |
17 |
18 |
19 |
20 | src
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/di/src/CallableResolver.php:
--------------------------------------------------------------------------------
1 | container = $container;
37 | }
38 |
39 | /**
40 | * Resolve toResolve into a closure that that the router can dispatch.
41 | *
42 | * If toResolve is of the format 'class:method', then try to extract 'class'
43 | * from the container otherwise instantiate it and then dispatch 'method'.
44 | *
45 | * @param mixed $toResolve
46 | *
47 | * @return callable
48 | *
49 | * @throws RuntimeException if the callable does not exist
50 | * @throws RuntimeException if the callable is not resolvable
51 | */
52 | public function resolve($toResolve): callable
53 | {
54 | if (is_callable($toResolve)) {
55 | return $toResolve;
56 | }
57 |
58 | if (!is_string($toResolve)) {
59 | $this->assertCallable($toResolve);
60 | }
61 |
62 | // check for slim callable as "class:method"
63 | if (preg_match(self::CALLABLE_PATTERN, $toResolve, $matches)) {
64 | $resolved = $this->resolveCallable($matches[1], $matches[2]);
65 | $this->assertCallable($resolved);
66 |
67 | return $resolved;
68 | }
69 |
70 | $resolved = $this->resolveCallable($toResolve);
71 | $this->assertCallable($resolved);
72 |
73 | return $resolved;
74 | }
75 |
76 | /**
77 | * Check if string is something in the DIC
78 | * that's callable or is a class name which has an __invoke() method.
79 | *
80 | * @param string $class
81 | * @param string $method
82 | *
83 | * @return callable
84 | *
85 | * @throws InvalidArgumentException
86 | * @throws RuntimeException if the callable does not exist
87 | */
88 | private function resolveCallable($class, $method = '__invoke'): callable
89 | {
90 | if ($cb = $this->container->getIfExist($class)) {
91 | return [$cb, $method];
92 | }
93 |
94 | if (!class_exists($class)) {
95 | throw new RuntimeException(sprintf('Callable %s does not exist', $class));
96 | }
97 |
98 | return [new $class($this->container), $method];
99 | }
100 |
101 | /**
102 | * @param Callable $callable
103 | *
104 | * @throws RuntimeException if the callable is not resolvable
105 | */
106 | private function assertCallable($callable): void
107 | {
108 | if (!is_callable($callable)) {
109 | throw new RuntimeException(sprintf('%s is not resolvable',
110 | is_array($callable) || is_object($callable) ? json_encode($callable) : $callable));
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/di/src/CallableResolverAwareTrait.php:
--------------------------------------------------------------------------------
1 | container instanceof ContainerInterface) {
40 | return $callable;
41 | }
42 |
43 | /** @var CallableResolverInterface $resolver */
44 | $resolver = $this->container->get('callableResolver');
45 |
46 | return $resolver->resolve($callable);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/di/src/DIManager.php:
--------------------------------------------------------------------------------
1 | [
31 | 'root' => null,// 'container name'=> a base Container instance
32 | 'children' => []
33 | ]
34 | ];
35 |
36 | /**
37 | * @return Container
38 | */
39 | public static function getDefault(): Container
40 | {
41 | return self::make('root', self::$defaultGroup);
42 | }
43 |
44 | /**
45 | * @param null|string $name
46 | *
47 | * @return Container
48 | */
49 | public static function getContainer(string $name = null): Container
50 | {
51 | return self::make($name);
52 | }
53 |
54 | /**
55 | * @param string $name
56 | * @param string $group
57 | *
58 | * @return Container
59 | */
60 | public static function make(string $name = null, string $group = null): Container
61 | {
62 | $group = $group ?: self::$defaultGroup;
63 |
64 | // No name, return default's base container.
65 | if (!$name) {
66 | if (empty(self::$containers[$group]['root'])) {
67 | $container = new Container;
68 | $container->name = 'di.root';
69 |
70 | self::$containers[$group]['root'] = $container;
71 | }
72 |
73 | return self::$containers[$group]['root'];
74 | }
75 |
76 | // Has name, we return children container.
77 | if (empty(self::$containers[$group][$name]) || !(self::$containers[$group][$name] instanceof Container)) {
78 | self::$containers[$group][$name] = new Container([], self::make(null, $group));
79 | self::$containers[$group][$name]->name = $name;
80 | }
81 |
82 | return self::$containers[$group][$name];
83 | }
84 |
85 | /**
86 | * setProfile
87 | *
88 | * @param string $group
89 | *
90 | * @return void
91 | */
92 | public static function setDefaultGroup($group = 'di'): void
93 | {
94 | $group = strtolower(trim($group));
95 |
96 | if (!isset(static::$containers[$group])) {
97 | static::$containers[$group] = [
98 | 'root' => null,
99 | 'children' => []
100 | ];
101 | }
102 |
103 | static::$defaultGroup = $group;
104 | }
105 |
106 | /**
107 | * Method to get property Profile
108 | *
109 | * @return string
110 | */
111 | public static function getDefaultGroup(): string
112 | {
113 | return static::$defaultGroup;
114 | }
115 |
116 | /**
117 | * reset
118 | *
119 | * @param string $group
120 | */
121 | public static function reset($group = null): void
122 | {
123 | if (!$group) {
124 | static::$containers = [];
125 | } else {
126 | static::$containers[$group] = [];
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/di/src/Exception/DependencyResolutionException.php:
--------------------------------------------------------------------------------
1 | 'id',
27 | * 'alias name2' => 'id'
28 | * ]
29 | */
30 | private $aliases = [];
31 |
32 | /**
33 | * set name alias
34 | *
35 | * @param string $name
36 | * @param array|string $alias
37 | */
38 | public function setAlias(string $name, $alias): void
39 | {
40 | if (!$name || !$alias) {
41 | return;
42 | }
43 |
44 | // setting
45 | if (is_array($alias)) {
46 | foreach ($alias as $aliasName) {
47 | if (!isset($this->aliases[$aliasName])) {
48 | $this->aliases[$aliasName] = $name;
49 | }
50 | }
51 | } else {
52 | $this->aliases[$alias] = $name;
53 | }
54 | }
55 |
56 | /**
57 | * @param string $alias
58 | *
59 | * @return mixed
60 | */
61 | public function resolveAlias(string $alias): string
62 | {
63 | return $this->aliases[$alias] ?? $alias;
64 | }
65 |
66 | /**
67 | * @param $alias
68 | *
69 | * @return bool
70 | */
71 | public function isAlias(string $alias): bool
72 | {
73 | return isset($this->aliases[$alias]);
74 | }
75 |
76 | /**
77 | * @return array
78 | */
79 | public function getAliases(): array
80 | {
81 | return $this->aliases;
82 | }
83 |
84 | /**
85 | * @param array $aliases
86 | *
87 | * @return $this
88 | */
89 | public function setAliases(array $aliases): self
90 | {
91 | $this->aliases = $aliases;
92 |
93 | return $this;
94 | }
95 |
96 | /**
97 | * @param array $aliases
98 | *
99 | * @return $this
100 | */
101 | public function addAliases(array $aliases): self
102 | {
103 | $this->aliases = array_merge($this->aliases, $aliases);
104 |
105 | return $this;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/di/src/ObjectItem.php:
--------------------------------------------------------------------------------
1 | arguments = $arguments;
63 |
64 | $this->shared = (bool)$shared;
65 | $this->locked = (bool)$locked;
66 |
67 | $this->setCallback($callback);
68 | }
69 |
70 | /**
71 | * __clone
72 | */
73 | private function __clone()
74 | {
75 | }
76 |
77 | /**
78 | * __destruct
79 | */
80 | public function __destruct()
81 | {
82 | $this->instance = $this->callback = $this->arguments = null;
83 | }
84 |
85 | /**
86 | * @param Container $container
87 | * @param bool $forceNew
88 | *
89 | * @return mixed|null
90 | */
91 | public function get(Container $container, $forceNew = false)
92 | {
93 | if ($this->shared) {
94 | if (!$this->instance || $forceNew) {
95 | $cb = $this->callback;
96 | $this->instance = $cb($container);
97 | }
98 |
99 | // 激活后就锁定,不允许再覆盖设置服务
100 | $this->locked = true;
101 | return $this->instance;
102 | }
103 |
104 | $cb = $this->callback;
105 |
106 | return $cb($container);
107 | }
108 |
109 | /**
110 | * @return mixed
111 | */
112 | public function getCallback()
113 | {
114 | return $this->callback;
115 | }
116 |
117 | /**
118 | * @param $callback
119 | */
120 | public function setCallback($callback): void
121 | {
122 | if (!method_exists($callback, '__invoke')) {
123 | $this->instance = $callback;
124 | $callback = function () use ($callback) {
125 | return $callback;
126 | };
127 | }
128 |
129 | $this->callback = $callback;
130 | }
131 |
132 | /**
133 | * @return array
134 | */
135 | public function getArguments(): array
136 | {
137 | return $this->arguments;
138 | }
139 |
140 | /**
141 | * 给服务设置参数,在获取服务实例前
142 | *
143 | * @param array $params 设置参数
144 | *
145 | * @throws InvalidArgumentException
146 | */
147 | public function setArguments(array $params): void
148 | {
149 | $this->arguments = $params;
150 | }
151 |
152 | /**
153 | * @return mixed
154 | */
155 | public function getInstance()
156 | {
157 | return $this->instance;
158 | }
159 |
160 | /**
161 | * @return bool
162 | */
163 | public function isLocked(): bool
164 | {
165 | return $this->locked;
166 | }
167 |
168 | /**
169 | * @param bool $locked
170 | */
171 | public function setLocked($locked = true): void
172 | {
173 | $this->locked = (bool)$locked;
174 | }
175 |
176 | /**
177 | * @return bool
178 | */
179 | public function isShared(): bool
180 | {
181 | return $this->shared;
182 | }
183 |
184 | /**
185 | * @param bool $shared
186 | */
187 | public function setShared($shared = true): void
188 | {
189 | $this->shared = (bool)$shared;
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/src/di/src/ServiceProviderInterface.php:
--------------------------------------------------------------------------------
1 | SomeClass::class,
26 | 's2' => [
27 | 'class' => MakeByStatic::class . '::factory',
28 | [
29 | [
30 | 'name' => 'test2'
31 | ]
32 | ]
33 | ],
34 | 's3' => [
35 | 'class' => MakeByMethod::class . '->factory',
36 | [
37 | [
38 | 'name' => 'test2'
39 | ]
40 | ]
41 | ]
42 | ]);
43 |
44 | $this->assertCount(3, $di);
45 | $this->assertTrue($di->has('s1'));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/di/test/MakeByMethod.php:
--------------------------------------------------------------------------------
1 | options = $options;
26 | }
27 |
28 | /**
29 | * @return array
30 | */
31 | public function getOptions(): array
32 | {
33 | return $this->options;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/di/test/boot.php:
--------------------------------------------------------------------------------
1 | 7.1.0",
21 | "toolkit/arr-utils": "~1.0",
22 | "toolkit/obj-utils": "~1.0",
23 | "toolkit/str-utils": "~1.0",
24 | "toolkit/sys-utils": "~1.0",
25 | "toolkit/file-utils": "~1.0",
26 | "toolkit/php-utils": "~1.0"
27 | },
28 | "autoload": {
29 | "psr-4": {
30 | "Toolkit\\Util\\": "src/Util",
31 | "Toolkit\\Traits\\": "src/Traits",
32 | "Toolkit\\Helper\\": "src/Helper"
33 | }
34 | },
35 | "suggest": {
36 | "inhere/php-validate": "Very lightweight data validate tool",
37 | "inhere/console": "a lightweight php console application library."
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/helper-utils/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 | test
16 |
17 |
18 |
19 |
20 |
21 | src
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Helper/AssertHelper.php:
--------------------------------------------------------------------------------
1 | $allowedClasses]);
37 | }
38 |
39 | /**
40 | * php对象转换成为数组
41 | * @param iterable|array|\Traversable $data
42 | * @param bool $recursive
43 | * @return array|bool
44 | */
45 | public static function toArray($data, $recursive = false)
46 | {
47 | // Ensure the input data is an array.
48 | if (\is_object($data)) {
49 | if ($data instanceof \Traversable) {
50 | $data = iterator_to_array($data);
51 | } elseif (method_exists($data, 'toArray')) {
52 | $data = $data->toArray();
53 | }
54 | } else {
55 | $data = (array)$data;
56 | }
57 |
58 | if ($recursive) {
59 | foreach ($data as &$value) {
60 | if (\is_array($value) || \is_object($value)) {
61 | $value = static::toArray($value, $recursive);
62 | }
63 | }
64 | }
65 |
66 | return $data;
67 | }
68 |
69 | /**
70 | * data to array
71 | * @param array|\Traversable $array
72 | * @param string $class
73 | * @return mixed
74 | */
75 | public static function toObject($array, $class = \stdClass::class)
76 | {
77 | $object = new $class;
78 |
79 | foreach ($array as $name => $value) {
80 | $name = trim($name);
81 |
82 | if (!$name || is_numeric($name)) {
83 | continue;
84 | }
85 |
86 | $object->$name = \is_array($value) ? self::toObject($value) : $value;
87 | }
88 |
89 | return $object;
90 | }
91 |
92 | /**
93 | * Sanitize a string
94 | * @param string $string String to sanitize
95 | * @param bool $clearTag clear html tag
96 | * @return string Sanitized string
97 | */
98 | public static function safeOutput($string, $clearTag = false): string
99 | {
100 | if (!$clearTag) {
101 | $string = strip_tags($string);
102 | }
103 |
104 | return @self::htmlentitiesUTF8($string);
105 | }
106 |
107 | /**
108 | * @param $string
109 | * @param int $type
110 | * @return array|string
111 | */
112 | public static function htmlentitiesUTF8($string, $type = ENT_QUOTES)
113 | {
114 | if (\is_array($string)) {
115 | return array_map([__CLASS__, 'htmlentitiesUTF8'], $string);
116 | }
117 |
118 | return htmlentities((string)$string, $type, 'utf-8');
119 | }
120 |
121 | /**
122 | * @param $string
123 | * @return string
124 | */
125 | public static function htmlentitiesDecodeUTF8($string): string
126 | {
127 | if (\is_array($string)) {
128 | $string = array_map([__CLASS__, 'htmlentitiesDecodeUTF8'], $string);
129 |
130 | return (string)array_shift($string);
131 | }
132 |
133 | return html_entity_decode((string)$string, ENT_QUOTES, 'utf-8');
134 | }
135 |
136 | /**
137 | * @param $argc
138 | * @param $argv
139 | * @return null
140 | */
141 | public static function argvToGET($argc, $argv)
142 | {
143 | if ($argc <= 1) {
144 | return true;
145 | }
146 |
147 | // get the first argument and parse it like a query string
148 | parse_str($argv[1], $args);
149 | if (!\is_array($args) || !\count($args)) {
150 | return true;
151 | }
152 |
153 | $_GET = array_merge($args, $_GET);
154 | $_SERVER['QUERY_STRING'] = $argv[1];
155 |
156 | return true;
157 | }
158 |
159 | /**
160 | * 清理数据的空白
161 | * @param $data array|string
162 | * @return array|string
163 | */
164 | public static function trim($data)
165 | {
166 | if (is_scalar($data)) {
167 | return trim($data);
168 | }
169 |
170 | array_walk_recursive($data, function (&$value) {
171 | $value = trim($value);
172 | });
173 |
174 | return $data;
175 | }
176 |
177 | /*
178 | * strip_tags — 从字符串中去除 HTML 和 PHP 标记
179 | * 由于 strip_tags() 无法实际验证 HTML,不完整或者破损标签将导致更多的数据被删除。
180 | * $allow_tags 允许的标记,多个以空格隔开
181 | **/
182 | public static function stripTags($data, $allow_tags = null)
183 | {
184 | if (\is_array($data)) {
185 | foreach ($data as $k => $v) {
186 | $data[$k] = self::stripTags($v, $allow_tags);
187 | }
188 |
189 | return $data;
190 | }
191 |
192 | if (\is_string($data) || is_numeric($data)) {
193 | return strip_tags($data, $allow_tags);
194 | }
195 |
196 | return false;
197 | }
198 |
199 | /**
200 | * 对数组或字符串进行加斜杠\转义处理 去除转义
201 | * 去除转义返回一个去除反斜线后的字符串(\' 转换为 ' 等等)。双反斜线(\\)被转换为单个反斜线(\)。
202 | * @param array|string $data 数据可以是字符串或数组
203 | * @param int $escape 进行转义 true 转义处理 false 去除转义
204 | * @param int $level 增强
205 | * @return array|string
206 | */
207 | public static function slashes($data, $escape = 1, $level = 0)
208 | {
209 | if (\is_array($data)) {
210 | foreach ((array)$data as $key => $value) {
211 | $data[$key] = self::slashes($value, $escape, $level);
212 | }
213 |
214 | return $data;
215 | }
216 |
217 | $data = trim($data);
218 |
219 | if (!$escape) {
220 | return stripslashes($data);
221 | }
222 |
223 | $data = addslashes($data);
224 |
225 | if ($level) {
226 | // 两个str_replace替换转义目的是防止黑客转换SQL编码进行攻击。
227 | $data = str_replace(['_', '%'], ["\_", "\%"], $data); // 转义掉_ %
228 | }
229 |
230 | return $data;
231 | }
232 |
233 | public static function escape_query($str): string
234 | {
235 | return strtr($str, [
236 | "\0" => '',
237 | "'" => ''',
238 | '"' => '"',
239 | "\\" => '\',
240 | // more secure
241 | '<' => '<',
242 | '>' => '>',
243 | ]);
244 | }
245 |
246 | /**
247 | * 对数据进行字符集转换处理,数据可以是字符串或数组及对象
248 | * @param array|string $data
249 | * @param $in_charset
250 | * @param $out_charset
251 | * @return array|string
252 | */
253 | public static function changeEncode($data, $in_charset = 'GBK', $out_charset = 'UTF-8')
254 | {
255 | if (\is_array($data)) {
256 |
257 | foreach ($data as $key => $value) {
258 | $data[$key] = self::changeEncode($value, $in_charset, $out_charset);
259 | }
260 |
261 | return $data;
262 | }
263 |
264 | if (\function_exists('mb_convert_encoding')) {
265 | return mb_convert_encoding($data, $out_charset, $in_charset);
266 | }
267 |
268 | return iconv($in_charset, $out_charset . '/' . '/IGNORE', $data);
269 | }
270 |
271 | }
272 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Helper/DateHelper.php:
--------------------------------------------------------------------------------
1 | static::getOption('host', 'localhost'),
84 | '{PORT}' => static::getOption('port', 3306),
85 | '{DBNAME}' => static::getOption('database'),
86 | '{CHARSET}' => static::getOption('charset', 'utf8')
87 | ]
88 | ];
89 | }
90 |
91 | /**
92 | * cubrid
93 | * @return array
94 | */
95 | protected static function cubrid(): array
96 | {
97 | return [
98 | 'cubrid:host={HOST};port={PORT};dbname={DBNAME}',
99 | [
100 | '{HOST}' => static::getOption('host', 'localhost'),
101 | '{PORT}' => static::getOption('port', 33000),
102 | '{DBNAME}' => static::getOption('database')
103 | ]
104 | ];
105 | }
106 |
107 | /**
108 | * dblib
109 | * @return array
110 | */
111 | protected static function dblib(): array
112 | {
113 | return [
114 | 'dblib:host={HOST};port={PORT};dbname={DBNAME}',
115 | [
116 | '{HOST}' => static::getOption('host', 'localhost'),
117 | '{PORT}' => static::getOption('port', 1433),
118 | '{DBNAME}' => static::getOption('database')
119 | ]
120 | ];
121 | }
122 |
123 | /**
124 | * firebird
125 | * @return array
126 | */
127 | protected static function firebird(): array
128 | {
129 | return [
130 | 'firebird:dbname={DBNAME}',
131 | [
132 | '{DBNAME}' => static::getOption('database')
133 | ]
134 | ];
135 | }
136 |
137 | /**
138 | * ibm
139 | * @return array
140 | */
141 | protected static function ibm(): array
142 | {
143 | if ($dsn = static::getOption('dsn')) {
144 | return [
145 | 'ibm:DSN={DSN}',
146 | [
147 | '{DSN}' => $dsn
148 | ]
149 | ];
150 | }
151 |
152 | return [
153 | 'ibm:hostname={HOST};port={PORT};database={DBNAME}',
154 | [
155 | '{HOST}' => static::getOption('host', 'localhost'),
156 | '{PORT}' => static::getOption('port', 56789),
157 | '{DBNAME}' => static::getOption('database')
158 | ]
159 | ];
160 | }
161 |
162 | /**
163 | * dblib
164 | * @return array
165 | */
166 | protected static function informix(): array
167 | {
168 | if ($dsn = static::getOption('dsn')) {
169 | return [
170 | 'informix:DSN={DSN}',
171 | [
172 | '{DSN}' => $dsn
173 | ]
174 | ];
175 | }
176 |
177 | return [
178 | 'informix:host={HOST};service={PORT};database={DBNAME};server={SERVER};protocol={PROTOCOL}',
179 | [
180 | '{HOST}' => static::getOption('host', 'localhost'),
181 | '{PORT}' => static::getOption('port', 1526),
182 | '{DBNAME}' => static::getOption('database'),
183 | '{SERVER}' => static::getOption('server'),
184 | '{PROTOCOL}' => static::getOption('protocol')
185 | ]
186 | ];
187 | }
188 |
189 | /**
190 | * mssql
191 | * @return array
192 | */
193 | protected static function mssql(): array
194 | {
195 | return [
196 | 'mssql:host={HOST};port={PORT};dbname={DBNAME}',
197 | [
198 | '{HOST}' => static::getOption('host', 'localhost'),
199 | '{PORT}' => static::getOption('port', 1433),
200 | '{DBNAME}' => static::getOption('database')
201 | ]
202 | ];
203 | }
204 |
205 | /**
206 | * oci
207 | * @return array
208 | */
209 | protected static function oci(): array
210 | {
211 | if ($dsn = static::getOption('dsn')) {
212 | return [
213 | 'oci:dbname={DSN};charset={CHARSET}',
214 | [
215 | '{DSN}' => $dsn,
216 | '{CHARSET}' => static::getOption('charset', 'AL32UTF8')
217 | ]
218 | ];
219 | }
220 |
221 | return [
222 | 'oci:dbname=//#HOST#:#PORT#/#DBNAME};charset={CHARSET}',
223 | [
224 | '{HOST}' => static::getOption('host', 'localhost'),
225 | '{PORT}' => static::getOption('port', 56789),
226 | '{DBNAME}' => static::getOption('database'),
227 | '{CHARSET}' => static::getOption('charset', 'AL32UTF8')
228 | ]
229 | ];
230 | }
231 |
232 | /**
233 | * odbc
234 | * @return array
235 | */
236 | protected static function odbc(): array
237 | {
238 | return [
239 | 'odbc:DSN={DSN};UID:#USER};PWD={PASSWORD}',
240 | [
241 | '{HOST}' => static::getOption('host', 'localhost'),
242 | '{USER}' => static::getOption('user', 1433),
243 | '{PASSWORD}' => static::getOption('password')
244 | ]
245 | ];
246 | }
247 |
248 | /**
249 | * pgsql
250 | * @return array
251 | */
252 | protected static function pgsql(): array
253 | {
254 | return [
255 | 'pgsql:host={HOST};port={PORT};dbname={DBNAME}',
256 | [
257 | '{HOST}' => static::getOption('host', 'localhost'),
258 | '{PORT}' => static::getOption('port', 5432),
259 | '{DBNAME}' => static::getOption('database', 'postgres')
260 | ]
261 | ];
262 | }
263 |
264 | /**
265 | * Alias of pgsql
266 | * @return array
267 | */
268 | protected static function postgresql(): array
269 | {
270 | return static::pgsql();
271 | }
272 |
273 | /**
274 | * sqlite
275 | * @return array
276 | */
277 | protected static function sqlite(): array
278 | {
279 | $version = (int)static::getOption('version');
280 |
281 | $format = $version === 2 ? 'sqlite2:{DBNAME}' : 'sqlite:{DBNAME}';
282 |
283 | return [
284 | $format,
285 | [
286 | '{DBNAME}' => static::getOption('database')
287 | ]
288 | ];
289 | }
290 |
291 | /**
292 | * sybase
293 | * @return array
294 | */
295 | protected static function sybase(): array
296 | {
297 | return [
298 | 'pgsql:host={HOST};port={PORT};dbname={DBNAME}',
299 | [
300 | '{HOST}' => static::getOption('host', 'localhost'),
301 | '{PORT}' => static::getOption('port', 1433),
302 | '{DBNAME}' => static::getOption('database')
303 | ]
304 | ];
305 | }
306 |
307 | /**
308 | * sybase
309 | * @return array
310 | */
311 | protected static function fourd(): array
312 | {
313 | return [
314 | '4D:host={HOST};charset=UTF-8',
315 | [
316 | '{HOST}' => static::getOption('host', 'localhost'),
317 | '{CHARSET}' => static::getOption('charset', 'UTF-8')
318 | ]
319 | ];
320 | }
321 |
322 | /**
323 | * getOption
324 | * @param string $name
325 | * @param string $default
326 | * @return mixed
327 | */
328 | protected static function getOption($name, $default = null)
329 | {
330 | return self::$options[$name] ?? $default;
331 | }
332 | }
333 |
334 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Helper/FormatHelper.php:
--------------------------------------------------------------------------------
1 | $format) {
38 | if ($secs >= $format[0]) {
39 | if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
40 | || $index === \count($timeFormats) - 1
41 | ) {
42 | if (2 === \count($format)) {
43 | return $format[1];
44 | }
45 |
46 | return floor($secs / $format[2]) . ' ' . $format[1];
47 | }
48 | }
49 | }
50 |
51 | return date('Y-m-d H:i:s', $secs);
52 | }
53 |
54 | /**
55 | * @param string $mTime value is microtime(1)
56 | * @return string
57 | */
58 | public static function microTime($mTime = null): string
59 | {
60 | if (!$mTime) {
61 | $mTime = microtime(true);
62 | }
63 |
64 | [$ts, $ms] = explode('.', sprintf('%.4f', $mTime));
65 |
66 | return date('Y/m/d H:i:s', $ts) . '.' . $ms;
67 | }
68 |
69 | /**
70 | * @param $memory
71 | * @return string
72 | * ```
73 | * Helper::memory(memory_get_usage(true));
74 | * ```
75 | */
76 | public static function memory($memory): string
77 | {
78 | if ($memory >= 1024 * 1024 * 1024) {
79 | return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
80 | }
81 |
82 | if ($memory >= 1024 * 1024) {
83 | return sprintf('%.1f MiB', $memory / 1024 / 1024);
84 | }
85 |
86 | if ($memory >= 1024) {
87 | return sprintf('%d KiB', $memory / 1024);
88 | }
89 |
90 | return sprintf('%d B', $memory);
91 | }
92 |
93 | /**
94 | * @param int $size
95 | * @return string
96 | * ```
97 | * Helper::size(memory_get_usage(true));
98 | * ```
99 | */
100 | public static function size(int $size): string
101 | {
102 | if ($size >= 1024 * 1024 * 1024) {
103 | return sprintf('%.1f Gb', $size / 1024 / 1024 / 1024);
104 | }
105 |
106 | if ($size >= 1024 * 1024) {
107 | return sprintf('%.1f Mb', $size / 1024 / 1024);
108 | }
109 |
110 | if ($size >= 1024) {
111 | return sprintf('%d Kb', $size / 1024);
112 | }
113 |
114 | return sprintf('%d b', $size);
115 | }
116 |
117 | /**
118 | * Format a number into a human readable format
119 | * e.g. 24962496 => 23.81M
120 | * @param $size
121 | * @param int $precision
122 | * @return string
123 | */
124 | public static function bytes($size, $precision = 2): string
125 | {
126 | if (!$size) {
127 | return '0';
128 | }
129 |
130 | $base = log($size) / log(1024);
131 | $suffixes = ['b', 'k', 'M', 'G', 'T'];
132 | $floorBase = floor($base);
133 |
134 | return round(1024 ** ($base - $floorBase), $precision) . $suffixes[(int)$floorBase];
135 | }
136 |
137 | /**
138 | * Convert a shorthand byte value from a PHP configuration directive to an integer value
139 | * @param string $value value to convert
140 | * @return int
141 | */
142 | public static function convertBytes($value): int
143 | {
144 | if (is_numeric($value)) {
145 | return $value;
146 | }
147 |
148 | $value_length = \strlen($value);
149 | $qty = (int)substr($value, 0, $value_length - 1);
150 | $unit = \strtolower(\substr($value, $value_length - 1));
151 | switch ($unit) {
152 | case 'k':
153 | $qty *= 1024;
154 | break;
155 | case 'm':
156 | $qty *= 1048576;
157 | break;
158 | case 'g':
159 | $qty *= 1073741824;
160 | break;
161 | }
162 |
163 | return $qty;
164 | }
165 |
166 | /**
167 | * Replaces & with & for XHTML compliance
168 | * @param string $text Text to process
169 | * @return string Processed string.
170 | */
171 | public static function ampReplace($text): string
172 | {
173 | $text = str_replace([
174 | '&&',
175 | '',
176 | '',
177 | '&',
178 | '*-*',
179 | '*--*',
180 | ], [
181 | '*--*',
182 | '*-*',
183 | '*-*',
184 | '&',
185 | '',
186 | '&&',
187 | ], $text);
188 |
189 | $text = (string)preg_replace('/|&(?![\w]+;)|/', '&', $text);
190 |
191 | return $text;
192 | }
193 |
194 | /**
195 | * Cleans text of all formatting and scripting code
196 | * @param string|null|array $text Text to clean
197 | * @return string Cleaned text.
198 | */
199 | public static function cleanText(string $text): string
200 | {
201 | $text = preg_replace('//si', '', $text);
202 | $text = preg_replace('/]*>([^<]+)<\/a>/is', '\2 (\1)', $text);
203 | $text = preg_replace('//', '', $text);
204 | $text = preg_replace('/{.+?}/', '', $text);
205 | $text = preg_replace('/ /', ' ', $text);
206 | $text = preg_replace('/&/', ' ', $text);
207 | $text = preg_replace('/"/', ' ', $text);
208 | $text = strip_tags($text);
209 | $text = htmlspecialchars($text);
210 |
211 | return $text;
212 | }
213 |
214 | /**
215 | * 返回删除注释和空格后的PHP源码(php_strip_whitespace)
216 | * @link http://cn2.php.net/manual/zh/function.php-strip-whitespace.php
217 | * @param string|bool $src
218 | * @return string
219 | */
220 | public static function phpCode(string $src): string
221 | {
222 | // Whitespaces left and right from this signs can be ignored
223 | static $IW = [
224 | T_CONCAT_EQUAL, // .=
225 | T_DOUBLE_ARROW, // =>
226 | T_BOOLEAN_AND, // &&
227 | T_BOOLEAN_OR, // ||
228 | T_IS_EQUAL, // ==
229 | T_IS_NOT_EQUAL, // != or <>
230 | T_IS_SMALLER_OR_EQUAL, // <=
231 | T_IS_GREATER_OR_EQUAL, // >=
232 | T_INC, // ++
233 | T_DEC, // --
234 | T_PLUS_EQUAL, // +=
235 | T_MINUS_EQUAL, // -=
236 | T_MUL_EQUAL, // *=
237 | T_DIV_EQUAL, // /=
238 | T_IS_IDENTICAL, // ===
239 | T_IS_NOT_IDENTICAL, // !==
240 | T_DOUBLE_COLON, // ::
241 | T_PAAMAYIM_NEKUDOTAYIM, // ::
242 | T_OBJECT_OPERATOR, // ->
243 | T_DOLLAR_OPEN_CURLY_BRACES, // ${
244 | T_AND_EQUAL, // &=
245 | T_MOD_EQUAL, // %=
246 | T_XOR_EQUAL, // ^=
247 | T_OR_EQUAL, // |=
248 | T_SL, // <<
249 | T_SR, // >>
250 | T_SL_EQUAL, // <<=
251 | T_SR_EQUAL, // >>=
252 | ];
253 |
254 | if (!$src) {
255 | return false;
256 | }
257 |
258 | if (is_file($src) && (!$src = file_get_contents($src))) {
259 | return false;
260 | }
261 |
262 | $tokens = token_get_all($src);
263 |
264 | $new = '';
265 | $c = \count($tokens);
266 | $iw = false; // ignore whitespace
267 | $ih = false; // in HEREDOC
268 | $ls = ''; // last sign
269 | $ot = null; // open tag
270 | for ($i = 0; $i < $c; $i++) {
271 | $token = $tokens[$i];
272 | if (\is_array($token)) {
273 | [$tn, $ts] = $token; // tokens: number, string, line
274 | $tname = token_name($tn);
275 | if ($tn === T_INLINE_HTML) {
276 | $new .= $ts;
277 | $iw = false;
278 | } elseif ($tn === T_OPEN_TAG) {
279 | if (strpos($ts, ' ') || strpos($ts, "\n") || strpos($ts, "\t") || strpos($ts, "\r")) {
280 | $ts = rtrim($ts);
281 | }
282 | $ts .= ' ';
283 | $new .= $ts;
284 | $ot = T_OPEN_TAG;
285 | $iw = true;
286 | } elseif ($tn === T_OPEN_TAG_WITH_ECHO) {
287 | $new .= $ts;
288 | $ot = T_OPEN_TAG_WITH_ECHO;
289 | $iw = true;
290 | } elseif ($tn === T_CLOSE_TAG) {
291 | if ($ot === T_OPEN_TAG_WITH_ECHO) {
292 | $new = rtrim($new, '; ');
293 | } else {
294 | $ts = ' ' . $ts;
295 | }
296 | $new .= $ts;
297 | $ot = null;
298 | $iw = false;
299 | } elseif (\in_array($tn, $IW, true)) {
300 | $new .= $ts;
301 | $iw = true;
302 | } elseif ($tn === T_CONSTANT_ENCAPSED_STRING || $tn === T_ENCAPSED_AND_WHITESPACE) {
303 | if ($ts[0] === '"') {
304 | $ts = addcslashes($ts, "\n\t\r");
305 | }
306 | $new .= $ts;
307 | $iw = true;
308 | } elseif ($tn === T_WHITESPACE) {
309 | $nt = @$tokens[$i + 1];
310 | if (!$iw && (!\is_string($nt) || $nt === '$') && !\in_array($nt[0], $IW, true)) {
311 | $new .= ' ';
312 | }
313 | $iw = false;
314 | } elseif ($tn === T_START_HEREDOC) {
315 | $new .= "<< 4096,
31 | 'addContentLengthHeader' => false,
32 | ], $options);
33 |
34 | // Send response
35 | if (!headers_sent()) {
36 | // Status
37 | header(sprintf(
38 | 'HTTP/%s %s %s',
39 | $response->getProtocolVersion(),
40 | $response->getStatusCode(),
41 | $response->getReasonPhrase()
42 | ));
43 |
44 | // Headers
45 | foreach ($response->getHeaders() as $name => $values) {
46 | /** @var array $values */
47 | foreach ($values as $value) {
48 | header(sprintf('%s: %s', $name, $value), false);
49 | }
50 | }
51 | }
52 |
53 | // Body
54 | if (!self::isEmptyResponse($response)) {
55 | $body = $response->getBody();
56 | if ($body->isSeekable()) {
57 | $body->rewind();
58 | }
59 |
60 | $chunkSize = $options['chunkSize'];
61 | $contentLength = $response->getHeaderLine('Content-Length');
62 |
63 | if (!$contentLength) {
64 | $contentLength = $body->getSize();
65 | }
66 |
67 | if (null !== $contentLength) {
68 | $amountToRead = $contentLength;
69 | while ($amountToRead > 0 && !$body->eof()) {
70 | $data = $body->read(min($chunkSize, $amountToRead));
71 | echo $data;
72 | $amountToRead -= \strlen($data);
73 |
74 | if (connection_status() !== CONNECTION_NORMAL) {
75 | break;
76 | }
77 | }
78 | } else {
79 | while (!$body->eof()) {
80 | echo $body->read($chunkSize);
81 | if (connection_status() !== CONNECTION_NORMAL) {
82 | break;
83 | }
84 | }
85 | }
86 | }
87 | }
88 |
89 | /**
90 | * Helper method, which returns true if the provided response must not output a body and false
91 | * if the response could have a body.
92 | * @see https://tools.ietf.org/html/rfc7231
93 | * @param ResponseInterface $response
94 | * @return bool
95 | */
96 | public static function isEmptyResponse(ResponseInterface $response): bool
97 | {
98 | if (method_exists($response, 'isEmpty')) {
99 | return $response->isEmpty();
100 | }
101 |
102 | return \in_array($response->getStatusCode(), [204, 205, 304], true);
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Helper/IntHelper.php:
--------------------------------------------------------------------------------
1 | $country_name,
47 | 'stateOrProvinceName' => $state_or_province_name,
48 | 'localityName' => $locality_name,
49 | 'organizationName' => $organization_name,
50 | 'organizationalUnitName' => $organizational_unit_name,
51 | 'commonName' => $common_name,
52 | 'emailAddress' => $email_address,
53 | ];
54 |
55 | // private key
56 | $priKey = openssl_pkey_new();
57 | $cert = openssl_csr_new($dn, $priKey);
58 | $cert = openssl_csr_sign($cert, null, $priKey, 365);
59 |
60 | $pem = [];
61 |
62 | openssl_x509_export($cert, $pem[0]);
63 | openssl_pkey_export($priKey, $pem[1], $pem_passphrase);
64 |
65 | $pem = implode($pem);
66 |
67 | return false !== file_put_contents($pem_file, $pem);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Helper/UtilHelper.php:
--------------------------------------------------------------------------------
1 | console.' . $type . '(' . $data . ');';
27 | }
28 |
29 | /**
30 | * @param string $pathname
31 | * @param int|string $projectId This must be a one character
32 | * @return int|string
33 | * @throws \LogicException
34 | */
35 | public static function ftok($pathname, $projectId)
36 | {
37 | if (\strlen($projectId) > 1) {
38 | throw new \LogicException("the project id must be a one character(int/str). Input: $projectId");
39 | }
40 |
41 | if (\function_exists('ftok')) {
42 | return ftok($pathname, $projectId);
43 | }
44 |
45 | if (!$st = @stat($pathname)) {
46 | return -1;
47 | }
48 |
49 | $key = sprintf('%u', ($st['ino'] & 0xffff) | (($st['dev'] & 0xff) << 16) | (($projectId & 0xff) << 24));
50 |
51 | return $key;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/AopProxyAwareTrait.php:
--------------------------------------------------------------------------------
1 | [handler0, handler1],
21 | * 'XyzClass::methodAfter' => [handler2, handler3],
22 | * ]
23 | */
24 | trait AopProxyAwareTrait
25 | {
26 | /**
27 | * @var array
28 | */
29 | private static $proxyPoints = ['before', 'after'];
30 |
31 | /**
32 | * @var mixed the proxy target is a class name or a object
33 | */
34 | private $proxyTarget;
35 |
36 | public function proxy($class, string $method = '', array $args = [])
37 | {
38 | $this->proxyTarget = $class;
39 |
40 | if ($method) {
41 | return $this->call($method, $args);
42 | }
43 |
44 | return $this;
45 | }
46 |
47 | /**
48 | * @param string $method
49 | * @param array $args
50 | * @return mixed
51 | * @throws \LogicException
52 | */
53 | public function call(string $method, array $args = [])
54 | {
55 | if (!$target = $this->proxyTarget) {
56 | throw new \LogicException('Please setting the proxy target [proxyTarget]');
57 | }
58 |
59 | // on before exec method
60 | if ($cbList = $this->findProxyCallback($target, $method)) {
61 | foreach ($cbList as $cb) {
62 | PhpHelper::call($cb, $target, $method, $args);
63 | }
64 | }
65 |
66 | // exec method
67 | $ret = PhpHelper::call([$target, $method], ...$args);
68 |
69 | // on after exec method
70 | if ($cb = $this->findProxyCallback($target, $method, 'after')) {
71 | foreach ($cbList as $cb) {
72 | PhpHelper::call($cb, $target, $method, $args);
73 | }
74 | }
75 |
76 | // clear
77 | $this->proxyTarget = null;
78 |
79 | return $ret;
80 | }
81 |
82 | /**
83 | * @param string $method
84 | * @param array $args
85 | * @return mixed
86 | */
87 | public function __call(string $method, array $args = [])
88 | {
89 | return $this->call($method, $args);
90 | }
91 |
92 | /**
93 | * @param array ...$args
94 | * @return $this|mixed
95 | * @throws \InvalidArgumentException
96 | */
97 | public function __invoke(...$args)
98 | {
99 | $num = \count($args);
100 |
101 | // only a object
102 | if ($num === 1) {
103 | return $this->proxy($args[0]);
104 | }
105 |
106 | // has object and method
107 | if ($num > 1) {
108 | $class = \array_shift($args);
109 | $method = \array_shift($args);
110 |
111 | return $this->proxy($class, $method, $args);
112 | }
113 |
114 | throw new \InvalidArgumentException('Missing parameters!');
115 | }
116 |
117 | /**
118 | * @param string|object $target
119 | * @param string $method
120 | * @param string $prefix
121 | * @return array
122 | */
123 | protected function findProxyCallback($target, $method, $prefix = 'before'): array: ?array
124 | {
125 | $className = \is_string($target) ? $target : \get_class($target);
126 |
127 | // e.g XyzClass::methodAfter
128 | $key = $className . '::' . $method . \ucfirst($prefix);
129 |
130 | return $this->proxyMap[$key] ?? [];
131 | }
132 |
133 | /**
134 | * @see addProxy()
135 | * @param $key
136 | * @param $handler
137 | * @param string $position
138 | * @return $this
139 | */
140 | public function register($key, $handler, $position = 'before'): self
141 | {
142 | return $this->addProxy($key, $handler, $position);
143 | }
144 |
145 | /**
146 | * @param string $key eg 'XyzClass::method'
147 | * @param callable $handler
148 | * @param string $position 'before' 'after'
149 | * @return $this
150 | */
151 | public function addProxy(string $key, $handler, string $position = 'before'): self
152 | {
153 | if (!\in_array($position, self::$proxyPoints, true)) {
154 | return $this;
155 | }
156 |
157 | $key .= \ucfirst($position);
158 | // save
159 | $this->proxyMap[$key][] = $handler;
160 |
161 | return $this;
162 | }
163 |
164 | /**
165 | * @param array $map
166 | * @return $this
167 | */
168 | public function addProxies(array $map): self
169 | {
170 | foreach ($map as $key => $handler) {
171 | $position = 'before';
172 |
173 | if (\is_array($handler)) {
174 | if (!isset($handler['handler'])) {
175 | continue;
176 | }
177 |
178 | $position = $handler['position'] ?? 'before';
179 | $handler = $handler['handler'];
180 | }
181 |
182 | $this->addProxy($key, $handler, $position);
183 | }
184 |
185 | return $this;
186 | }
187 |
188 | /**
189 | * @return array
190 | */
191 | public static function getProxyPoints(): array
192 | {
193 | return self::$proxyPoints;
194 | }
195 |
196 | /**
197 | * @return mixed
198 | */
199 | public function getProxyTarget()
200 | {
201 | return $this->proxyTarget;
202 | }
203 |
204 | /**
205 | * @return array
206 | */
207 | public function getProxyMap(): array
208 | {
209 | return $this->proxyMap;
210 | }
211 |
212 | /**
213 | * @param array $proxyMap
214 | */
215 | public function setProxyMap(array $proxyMap): void: void
216 | {
217 | $this->proxyMap = $proxyMap;
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Config/ConfigTrait.php:
--------------------------------------------------------------------------------
1 | config);
29 | }
30 |
31 | /**
32 | * Method to get property Options
33 | * @param string $name
34 | * @param mixed $default
35 | * @return mixed
36 | */
37 | public function getValue(string $name, $default = null)
38 | {
39 | $value = Arr::getByPath($this->config, $name, $default);
40 |
41 | if ($value && $value instanceof \Closure) {
42 | $value = $value();
43 | }
44 |
45 | return $value;
46 | }
47 |
48 | /**
49 | * Method to set property config
50 | * @param string $name
51 | * @param mixed $value
52 | * @return static Return self to support chaining.
53 | */
54 | public function setValue($name, $value)
55 | {
56 | $this->config[$name] = $value;
57 |
58 | return $this;
59 | }
60 |
61 | /**
62 | * delete a option
63 | * @param $name
64 | * @return mixed|null
65 | */
66 | public function delValue($name)
67 | {
68 | $value = null;
69 |
70 | if ($this->hasConfig($name)) {
71 | $value = $this->getValue($name);
72 |
73 | unset($this->config[$name]);
74 | }
75 |
76 | return $value;
77 | }
78 |
79 | /**
80 | * Method to get property Options
81 | * @param string|null $key
82 | * @return array
83 | */
84 | public function getConfig(string $key = null): array
85 | {
86 | if ($key) {
87 | return $this->getValue($key);
88 | }
89 |
90 | return $this->config;
91 | }
92 |
93 | /**
94 | * Method to set property config
95 | * @param array $config
96 | * @param bool $loopMerge
97 | * @return static Return self to support chaining.
98 | */
99 | public function setConfig(array $config, $loopMerge = true)
100 | {
101 | $this->config = $loopMerge ? Arr::merge($this->config, $config) : $config;
102 |
103 | return $this;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Config/LiteConfigTrait.php:
--------------------------------------------------------------------------------
1 | config);
27 | }
28 |
29 | /**
30 | * Method to get property Options
31 | * @param string $name
32 | * @param mixed $default
33 | * @return mixed
34 | */
35 | public function getValue($name, $default = null)
36 | {
37 | $value = array_key_exists($name, $this->config) ? $this->config[$name] : $default;
38 |
39 | if ($value && ($value instanceof \Closure)) {
40 | $value = $value();
41 | }
42 |
43 | return $value;
44 | }
45 |
46 | /**
47 | * Method to set property config
48 | * @param string $name
49 | * @param mixed $value
50 | * @return static Return self to support chaining.
51 | */
52 | public function setValue($name, $value)
53 | {
54 | $this->config[$name] = $value;
55 |
56 | return $this;
57 | }
58 |
59 | /**
60 | * delete a option
61 | * @param $name
62 | * @return mixed|null
63 | */
64 | public function delValue($name)
65 | {
66 | $value = null;
67 |
68 | if ($this->hasConfig($name)) {
69 | $value = $this->getValue($name);
70 |
71 | unset($this->config[$name]);
72 | }
73 |
74 | return $value;
75 | }
76 |
77 | /**
78 | * Method to get property Options
79 | * @param string|null $key
80 | * @return array
81 | */
82 | public function getConfig($key = null): array
83 | {
84 | if ($key) {
85 | return $this->getValue($key);
86 | }
87 |
88 | return $this->config;
89 | }
90 |
91 | /**
92 | * Method to set property config
93 | * @param array $config
94 | * @param bool $merge
95 | * @return static Return self to support chaining.
96 | */
97 | public function setConfig(array $config, $merge = true)
98 | {
99 | $this->config = $merge ? array_merge($this->config, $config) : $config;
100 |
101 | return $this;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Config/LiteOptionsTrait.php:
--------------------------------------------------------------------------------
1 | options);
27 | }
28 |
29 | /**
30 | * Method to get property Options
31 | * @param string $name
32 | * @param mixed $default
33 | * @return mixed
34 | */
35 | public function getOption(string $name, $default = null)
36 | {
37 | $value = array_key_exists($name, $this->options) ? $this->options[$name] : $default;
38 |
39 | if ($value && ($value instanceof \Closure)) {
40 | $value = $value();
41 | }
42 |
43 | return $value;
44 | }
45 |
46 | /**
47 | * Method to set property options
48 | * @param string $name
49 | * @param mixed $value
50 | * @return static Return self to support chaining.
51 | */
52 | public function setOption($name, $value)
53 | {
54 | $this->options[$name] = $value;
55 |
56 | return $this;
57 | }
58 |
59 | /**
60 | * delete a option
61 | * @param $name
62 | * @return mixed|null
63 | */
64 | public function delOption($name)
65 | {
66 | $value = null;
67 |
68 | if ($this->hasOption($name)) {
69 | $value = $this->getOption($name);
70 |
71 | unset($this->options[$name]);
72 | }
73 |
74 | return $value;
75 | }
76 |
77 | /**
78 | * Method to get property Options
79 | * @return array
80 | */
81 | public function getOptions(): array
82 | {
83 | return $this->options;
84 | }
85 |
86 | /**
87 | * Method to set property options
88 | * @param array $options
89 | * @param bool $merge
90 | * @return static Return self to support chaining.
91 | */
92 | public function setOptions(array $options, $merge = true)
93 | {
94 | $this->options = $merge ? array_merge($this->options, $options) : $options;
95 |
96 | return $this;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Config/OptionsTrait.php:
--------------------------------------------------------------------------------
1 | options);
29 | }
30 |
31 | /**
32 | * Method to get property Options
33 | * @param string $name
34 | * @param mixed $default
35 | * @return mixed
36 | */
37 | public function getOption(string $name, $default = null)
38 | {
39 | $value = array_key_exists($name, $this->options) ? $this->options[$name] : $default;
40 |
41 | if ($value && ($value instanceof \Closure)) {
42 | $value = $value();
43 | }
44 |
45 | return $value;
46 | }
47 |
48 | /**
49 | * Method to set property options
50 | * @param string $name
51 | * @param mixed $value
52 | * @return static Return self to support chaining.
53 | */
54 | public function setOption($name, $value)
55 | {
56 | $this->options[$name] = $value;
57 |
58 | return $this;
59 | }
60 |
61 | /**
62 | * delete a option
63 | * @param $name
64 | * @return mixed|null
65 | */
66 | public function delOption($name)
67 | {
68 | $value = null;
69 |
70 | if ($this->hasOption($name)) {
71 | $value = $this->getOption($name);
72 |
73 | unset($this->options[$name]);
74 | }
75 |
76 | return $value;
77 | }
78 |
79 | /**
80 | * Method to get property Options
81 | * @return array
82 | */
83 | public function getOptions(): array
84 | {
85 | return $this->options;
86 | }
87 |
88 | /**
89 | * Method to set property options
90 | * @param array $options
91 | * @param bool $merge
92 | * @return static Return self to support chaining.
93 | */
94 | public function setOptions(array $options, $merge = true)
95 | {
96 | $this->options = $merge ? Arr::merge($this->options, $options) : $options;
97 |
98 | return $this;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Event/EventTrait.php:
--------------------------------------------------------------------------------
1 | bool, // is once event
31 | * ]
32 | */
33 | private $events = [];
34 |
35 | /**
36 | * @var array
37 | */
38 | private $eventHandlers = [];
39 |
40 | /**
41 | * register a event handler
42 | * @param $event
43 | * @param callable $handler
44 | * @param bool $once
45 | */
46 | public function on($event, callable $handler, $once = false): void
47 | {
48 | if ($this->isSupportedEvent($event)) {
49 | $this->eventHandlers[$event][] = $handler;
50 | $this->events[$event] = (bool)$once;
51 | }
52 | }
53 |
54 | /**
55 | * register a once event handler
56 | * @param $event
57 | * @param callable $handler
58 | */
59 | public function once($event, callable $handler): void
60 | {
61 | $this->on($event, $handler, true);
62 | }
63 |
64 | /**
65 | * trigger event
66 | * @param $event
67 | * @param array $args
68 | * @return bool
69 | */
70 | public function fire($event, array $args = []): bool
71 | {
72 | if (!isset($this->events[$event])) {
73 | return false;
74 | }
75 |
76 | // call event handlers of the event.
77 | foreach ((array)$this->eventHandlers[$event] as $cb) {
78 | // return FALSE to stop go on handle.
79 | if (false === PhpHelper::call($cb, ...$args)) {
80 | break;
81 | }
82 | }
83 |
84 | // is a once event, remove it
85 | if ($this->events[$event]) {
86 | return $this->off($event);
87 | }
88 |
89 | return true;
90 | }
91 |
92 | /**
93 | * remove event and it's handlers
94 | * @param string $event
95 | * @return mixed
96 | */
97 | public function off($event)
98 | {
99 | if ($this->hasEvent($event)) {
100 | $handler = $this->eventHandlers[$event];
101 |
102 | unset($this->events[$event], $this->eventHandlers[$event]);
103 |
104 | return $handler;
105 | }
106 |
107 | return null;
108 | }
109 |
110 | /**
111 | * clearEvents
112 | */
113 | public function clearEvents(): void
114 | {
115 | $this->events = $this->eventHandlers = [];
116 | }
117 |
118 | /**
119 | * @param $event
120 | * @return bool
121 | */
122 | public function hasEvent($event): bool
123 | {
124 | return isset($this->events[$event]);
125 | }
126 |
127 | /**
128 | * @param $event
129 | * @return bool
130 | */
131 | public function isOnce($event): bool
132 | {
133 | if ($this->hasEvent($event)) {
134 | return $this->events[$event];
135 | }
136 |
137 | return false;
138 | }
139 |
140 | /**
141 | * check $name is a supported event name
142 | * @param $event
143 | * @return bool
144 | */
145 | public function isSupportedEvent($event): bool
146 | {
147 | if (!$event || !preg_match('/[a-zA-z][\w-]+/', $event)) {
148 | return false;
149 | }
150 |
151 | if ($ets = $this->supportedEvents) {
152 | return \in_array($event, $ets, true);
153 | }
154 |
155 | return true;
156 | }
157 |
158 | /**
159 | * @return array
160 | */
161 | public function getSupportEvents(): array
162 | {
163 | return $this->supportedEvents;
164 | }
165 |
166 | /**
167 | * @param array $supportedEvents
168 | */
169 | public function setSupportEvents(array $supportedEvents): void
170 | {
171 | $this->supportedEvents = $supportedEvents;
172 | }
173 |
174 | /**
175 | * @return array
176 | */
177 | public function getEvents(): array
178 | {
179 | return $this->events;
180 | }
181 |
182 | /**
183 | * @return int
184 | */
185 | public function getEventCount(): int
186 | {
187 | return \count($this->events);
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Event/FixedEventStaticTrait.php:
--------------------------------------------------------------------------------
1 | bool, // is once event
31 | * ]
32 | */
33 | private static $events = [];
34 |
35 | /**
36 | * events and handlers
37 | * @var array
38 | * [
39 | * 'event' => callable, // event handler
40 | * ]
41 | */
42 | private static $eventHandlers = [];
43 |
44 | /**
45 | * register a event handler
46 | * @param $event
47 | * @param callable $handler
48 | * @param bool $once
49 | */
50 | public static function on($event, callable $handler, $once = false): void
51 | {
52 | if (self::isSupportedEvent($event)) {
53 | self::$eventHandlers[$event][] = $handler;
54 | self::$events[$event] = (bool)$once;
55 | }
56 | }
57 |
58 | /**
59 | * register a once event handler
60 | * @param $event
61 | * @param callable $handler
62 | */
63 | public static function once($event, callable $handler): void
64 | {
65 | self::on($event, $handler, true);
66 | }
67 |
68 | /**
69 | * trigger event
70 | * @param $event
71 | * @param array $args
72 | * @return bool
73 | */
74 | public static function fire($event, array $args = []): bool
75 | {
76 | if (!isset(self::$events[$event])) {
77 | return false;
78 | }
79 |
80 | // call event handlers of the event.
81 | foreach ((array)self::$eventHandlers[$event] as $cb) {
82 | // return FALSE to stop go on handle.
83 | if (false === PhpHelper::call($cb, ...$args)) {
84 | break;
85 | }
86 | }
87 |
88 | // is a once event, remove it
89 | if (self::$events[$event]) {
90 | return self::off($event);
91 | }
92 |
93 | return true;
94 | }
95 |
96 | /**
97 | * remove event and it's handlers
98 | * @param $event
99 | * @return bool
100 | */
101 | public static function off($event): bool
102 | {
103 | if (self::hasEvent($event)) {
104 | unset(self::$events[$event], self::$eventHandlers[$event]);
105 |
106 | return true;
107 | }
108 |
109 | return false;
110 | }
111 |
112 | /**
113 | * @param $event
114 | * @return bool
115 | */
116 | public static function hasEvent($event): bool
117 | {
118 | return isset(self::$events[$event]);
119 | }
120 |
121 | /**
122 | * @param $event
123 | * @return bool
124 | */
125 | public static function isOnce($event): bool
126 | {
127 | if (self::hasEvent($event)) {
128 | return self::$events[$event];
129 | }
130 |
131 | return false;
132 | }
133 |
134 | /**
135 | * check $name is a supported event name
136 | * @param $event
137 | * @return bool
138 | */
139 | public static function isSupportedEvent($event): bool
140 | {
141 | if (!$event || !preg_match('/[a-zA-z][\w-]+/', $event)) {
142 | return false;
143 | }
144 |
145 | if ($ets = self::$supportedEvents) {
146 | return \in_array($event, $ets, true);
147 | }
148 |
149 | return true;
150 | }
151 |
152 | /**
153 | * @return array
154 | */
155 | public static function getSupportEvents(): array
156 | {
157 | return self::$supportedEvents;
158 | }
159 |
160 | /**
161 | * @param array $supportedEvents
162 | */
163 | public static function setSupportEvents(array $supportedEvents): void
164 | {
165 | self::$supportedEvents = $supportedEvents;
166 | }
167 |
168 | /**
169 | * @return array
170 | */
171 | public static function getEvents(): array
172 | {
173 | return self::$events;
174 | }
175 |
176 | /**
177 | * @return int
178 | */
179 | public static function countEvents(): int
180 | {
181 | return \count(self::$events);
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Event/FixedEventTrait.php:
--------------------------------------------------------------------------------
1 | getSupportedEvents(), true);
40 | }
41 |
42 | /**
43 | * @param $event
44 | * @return bool
45 | */
46 | public function hasEventHandler($event): bool
47 | {
48 | if (false === ($key = array_search($event, $this->getSupportedEvents(), true))) {
49 | return false;
50 | }
51 |
52 | return isset($this->eventHandlers[$key]);
53 | }
54 |
55 | /**
56 | * @return \SplFixedArray
57 | */
58 | public function getEventHandlers(): \SplFixedArray
59 | {
60 | return $this->eventHandlers;
61 | }
62 |
63 | /**
64 | * @return int
65 | */
66 | public function getEventCount(): int
67 | {
68 | return $this->eventHandlers->count();
69 | }
70 |
71 | /**
72 | * @param string $event
73 | * @return callable
74 | */
75 | public function getEventHandler(string $event): callable
76 | {
77 | if (false === ($key = array_search($event, $this->getSupportedEvents(), true))) {
78 | return null;
79 | }
80 |
81 | if (!isset($this->eventHandlers[$key])) {
82 | return null;
83 | }
84 |
85 | return $this->eventHandlers[$key];
86 | }
87 |
88 | /////////////////////////////////////////////////////////////////////////////////////////
89 | /// events method
90 | /////////////////////////////////////////////////////////////////////////////////////////
91 |
92 | /**
93 | * register a event callback
94 | * @param string $event event name
95 | * @param callable $cb event callback
96 | * @param bool $replace replace exists's event cb
97 | * @throws \InvalidArgumentException
98 | */
99 | public function on(string $event, callable $cb, bool $replace = false): void
100 | {
101 | if (false === ($key = array_search($event, $this->getSupportedEvents(), true))) {
102 | $sup = implode(',', $this->getSupportedEvents());
103 |
104 | throw new \InvalidArgumentException("The want registered event [$event] is not supported. Supported: $sup");
105 | }
106 |
107 | // init property
108 | if ($this->eventHandlers === null) {
109 | $this->eventHandlers = new \SplFixedArray(\count($this->getSupportedEvents()));
110 | }
111 |
112 | if (!$replace && isset($this->eventHandlers[$key])) {
113 | throw new \InvalidArgumentException("The want registered event [$event] have been registered! don't allow replace.");
114 | }
115 |
116 | $this->eventHandlers[$key] = $cb;
117 | }
118 |
119 | /**
120 | * remove event handler
121 | * @param string $event
122 | * @return bool
123 | */
124 | public function off(string $event): bool
125 | {
126 | if (false === ($key = array_search($event, $this->getSupportedEvents(), true))) {
127 | return null;
128 | }
129 |
130 | if (!isset($this->eventHandlers[$key]) || !($cb = $this->eventHandlers[$key])) {
131 | return null;
132 | }
133 |
134 | $this->eventHandlers[$key] = null;
135 |
136 | return $cb;
137 | }
138 |
139 | /**
140 | * @param string $event
141 | * @param array $args
142 | * @return mixed
143 | * @throws \InvalidArgumentException
144 | */
145 | protected function fire(string $event, array $args = [])
146 | {
147 | if (false === ($key = array_search($event, $this->getSupportedEvents(), true))) {
148 | throw new \InvalidArgumentException("Trigger a not exists's event: $event.");
149 | }
150 |
151 | if (!isset($this->eventHandlers[$key]) || !($cb = $this->eventHandlers[$key])) {
152 | return null;
153 | }
154 |
155 | return PhpHelper::call($cb, ...$args);
156 | }
157 |
158 | }
159 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/Event/LiteEventStaticTrait.php:
--------------------------------------------------------------------------------
1 | _events[$name])) {
37 | $this->_events[$name] = $cb;
38 | }
39 | }
40 |
41 | /**
42 | * @param string $name
43 | * @param array $args
44 | * @return mixed
45 | */
46 | protected function fire($name, array $args = [])
47 | {
48 | if (!isset($this->_events[$name]) || !($cb = $this->_events[$name])) {
49 | return null;
50 | }
51 |
52 | return Php::call($cb, ...$args);
53 | }
54 |
55 | /**
56 | * @param $name
57 | * @return mixed
58 | */
59 | public function off($name)
60 | {
61 | $cb = null;
62 |
63 | if (isset($this->_events[$name])) {
64 | $cb = $this->_events[$name];
65 | unset($this->_events[$name]);
66 | }
67 |
68 | return $cb;
69 | }
70 |
71 | /**
72 | * @param string $name
73 | * @return mixed
74 | */
75 | public function getEventHandler($name)
76 | {
77 | return $this->_events[$name] ?? null;
78 | }
79 |
80 | /**
81 | * @return array
82 | */
83 | public function getEvents(): array
84 | {
85 | return $this->_events;
86 | }
87 |
88 | /**
89 | * @return int
90 | */
91 | public function getEventCount(): int
92 | {
93 | return \count($this->_events);
94 | }
95 |
96 | /**
97 | * clearEvents
98 | */
99 | public function clearEvents(): void
100 | {
101 | $this->_events = [];
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/LiteContainerStaticTrait.php:
--------------------------------------------------------------------------------
1 | logger = function(){
161 | * return new xx\yy\Logger;
162 | * };
163 | * ```
164 | * @param string $name
165 | * @param mixed $service
166 | * @return bool
167 | */
168 | public function __set($name, $service)
169 | {
170 | return static::set($name, $service);
171 | }
172 |
173 | /**
174 | * allow call service by property
175 | * ```
176 | * $logger = $app->logger;
177 | * ```
178 | * @param string $name service name
179 | * @return mixed
180 | */
181 | public function __get($name)
182 | {
183 | return static::get($name);
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/LiteContainerTrait.php:
--------------------------------------------------------------------------------
1 | set($name, $service, $replace);
43 |
44 | return $this;
45 | }
46 |
47 | /**
48 | * register a app service
49 | * @param string $name
50 | * @param mixed $service service
51 | * @param bool $replace replace exists service
52 | * @return bool
53 | * @throws \LogicException
54 | */
55 | public function set($name, $service, $replace = false): bool
56 | {
57 | // have been used.
58 | if (isset(self::$instances[$name])) {
59 | throw new \LogicException("The service [$name] have been instanced, don't allow override it.");
60 | }
61 |
62 | // setting
63 | if ($replace || !isset(self::$services[$name])) {
64 | self::$services[$name] = $service;
65 | }
66 |
67 | return true;
68 | }
69 |
70 | /**
71 | * get a app service by name
72 | * if is a closure, only run once.
73 | * @param string $name
74 | * @param bool $call if service is 'Closure', call it.
75 | * @return mixed
76 | * @throws \RuntimeException
77 | */
78 | public function get($name, $call = true)
79 | {
80 | if (!isset(self::$services[$name])) {
81 | throw new \RuntimeException("The service [$name] don't register.");
82 | }
83 |
84 | $service = self::$services[$name];
85 |
86 | if (\is_object($service) && $service instanceof \Closure && $call) {
87 | if (!isset(self::$instances[$name])) {
88 | self::$instances[$name] = $service($this);
89 | }
90 |
91 | return self::$instances[$name];
92 | }
93 |
94 | return $service;
95 | }
96 |
97 | /**
98 | * @param string $name
99 | * @return mixed
100 | * @throws \RuntimeException
101 | */
102 | public function raw($name)
103 | {
104 | if (!isset(self::$services[$name])) {
105 | throw new \RuntimeException("The service [$name] don't register.");
106 | }
107 |
108 | return self::$services[$name];
109 | }
110 |
111 | /**
112 | * create a app service by name
113 | * it always return a new instance.
114 | * @param string $name
115 | * @return mixed
116 | * @throws \RuntimeException
117 | */
118 | public function factory($name)
119 | {
120 | if (!isset(self::$services[$name])) {
121 | throw new \RuntimeException("The service [$name] don't register.");
122 | }
123 |
124 | $service = self::$services[$name];
125 |
126 | if (\is_object($service) && method_exists($service, '__invoke')) {
127 | return $service($this);
128 | }
129 |
130 | return $service;
131 | }
132 |
133 | /**
134 | * @param $name
135 | * @return bool
136 | */
137 | public function has($name): bool
138 | {
139 | return isset(self::$services[$name]);
140 | }
141 |
142 | /**
143 | * @return array
144 | */
145 | public function getServiceNames(): array
146 | {
147 | return array_keys(self::$services);
148 | }
149 |
150 | /**
151 | * @param $name
152 | * @return bool
153 | */
154 | public function __isset($name)
155 | {
156 | return $this->has($name);
157 | }
158 |
159 | /**
160 | * allow register a app service by property
161 | * ```
162 | * $app->logger = function(){
163 | * return new xx\yy\Logger;
164 | * };
165 | * ```
166 | * @param string $name
167 | * @param mixed $service
168 | * @return bool
169 | */
170 | public function __set($name, $service)
171 | {
172 | return $this->set($name, $service);
173 | }
174 |
175 | /**
176 | * allow call service by property
177 | * ```
178 | * $logger = $app->logger;
179 | * ```
180 | * @param string $name service name
181 | * @return mixed
182 | */
183 | public function __get($name)
184 | {
185 | return $this->get($name);
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/LogProfileTrait.php:
--------------------------------------------------------------------------------
1 | [
40 | 'startTime' => microtime(true),
41 | 'startMem' => memory_get_usage(),
42 | ],
43 | '_profile_start' => $context,
44 | '_profile_end' => null,
45 | ];
46 |
47 | $this->activeKey = $category . '|' . $name;
48 | $this->profiles[$category][$name] = $data;
49 | }
50 |
51 | /**
52 | * mark data analysis end
53 | * @param string|null $title
54 | * @param array $context
55 | */
56 | public function profileEnd($title = null, array $context = []): void
57 | {
58 | if (!$this->activeKey) {
59 | return;
60 | }
61 |
62 | [$category, $name] = explode('|', $this->activeKey);
63 |
64 | if (isset($this->profiles[$category][$name])) {
65 | $data = $this->profiles[$category][$name];
66 |
67 | $old = $data['_profile_stats'];
68 | $data['_profile_stats'] = PhpHelper::runtime($old['startTime'], $old['startMem']);
69 | $data['_profile_end'] = $context;
70 |
71 | $title = $category . ' - ' . ($title ?: $name);
72 |
73 | $this->activeKey = null;
74 | $this->log(Logger::DEBUG, $title, $data);
75 | }
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/LogShortTrait.php:
--------------------------------------------------------------------------------
1 | resolveAlias($name);
31 | }
32 |
33 | foreach ((array)$alias as $aliasName) {
34 | if (!isset($this->aliases[$aliasName])) {
35 | $this->aliases[$aliasName] = $name;
36 | }
37 | }
38 |
39 | return true;
40 | }
41 |
42 | /**
43 | * @param string $alias
44 | * @return mixed
45 | */
46 | public function resolveAlias(string $alias)
47 | {
48 | return $this->aliases[$alias] ?? $alias;
49 | }
50 |
51 | /**
52 | * @param $alias
53 | * @return bool
54 | */
55 | public function hasAlias($alias): bool
56 | {
57 | return isset($this->aliases[$alias]);
58 | }
59 |
60 | /**
61 | * @return array
62 | */
63 | public function getAliases(): array
64 | {
65 | return $this->aliases;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/PathAliasTrait.php:
--------------------------------------------------------------------------------
1 | $realPath) {
77 | // 1th char must is '@'
78 | if (!$alias || $alias[0] !== '@') {
79 | continue;
80 | }
81 |
82 | self::$aliases[$alias] = self::alias($realPath);
83 | }
84 | }
85 |
86 | /**
87 | * @return array
88 | */
89 | public static function getAliases(): array
90 | {
91 | return self::$aliases;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/PathResolverTrait.php:
--------------------------------------------------------------------------------
1 | pathResolver) {
31 | return $path;
32 | }
33 |
34 | return Php::call($this->pathResolver, $path);
35 | }
36 |
37 | /**
38 | * @return callable
39 | */
40 | public function getPathResolver(): callable
41 | {
42 | return $this->pathResolver;
43 | }
44 |
45 | /**
46 | * @param callable $pathResolver
47 | */
48 | public function setPathResolver(callable $pathResolver): void
49 | {
50 | $this->pathResolver = $pathResolver;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Traits/RuntimeProfileTrait.php:
--------------------------------------------------------------------------------
1 | [
45 | 'startTime' => microtime(true),
46 | 'startMem' => memory_get_usage(),
47 | ],
48 | '_profile_start' => $context,
49 | '_profile_end' => null,
50 | '_profile_msg' => null,
51 | ];
52 |
53 | $profileKey = $category . '|' . $name;
54 |
55 | if (\in_array($profileKey, self::$keyQueue, 1)) {
56 | throw new \InvalidArgumentException("Your added profile name [$name] have been exists!");
57 | }
58 |
59 | self::$keyQueue[] = $profileKey;
60 | self::$profiles[$category][$name] = $data;
61 | }
62 |
63 | /**
64 | * mark data analysis end
65 | * @param string|null $msg
66 | * @param array $context
67 | * @return bool|array
68 | */
69 | public static function profileEnd($msg = null, array $context = [])
70 | {
71 | if (!$latestKey = array_pop(self::$keyQueue)) {
72 | return false;
73 | }
74 |
75 | [$category, $name] = explode('|', $latestKey);
76 |
77 | if (isset(self::$profiles[$category][$name])) {
78 | $data = self::$profiles[$category][$name];
79 |
80 | $old = $data['_profile_stats'];
81 | $data['_profile_stats'] = PhpHelper::runtime($old['startTime'], $old['startMem']);
82 | $data['_profile_end'] = $context;
83 | $data['_profile_msg'] = $msg;
84 |
85 | // $title = $category . ' - ' . ($title ?: $name);
86 |
87 | self::$profiles[$category][$name] = $data;
88 | // self::$log(Logger::DEBUG, $title, $data);
89 |
90 | return $data;
91 | }
92 |
93 | return false;
94 | }
95 |
96 | /**
97 | * @param null|string $name
98 | * @param string $category
99 | * @return array
100 | */
101 | public static function getProfileData($name = null, $category = 'application'): array
102 | {
103 | if ($name) {
104 | return self::$profiles[$category][$name] ?? [];
105 | }
106 |
107 | if ($category) {
108 | return self::$profiles[$category] ?? [];
109 | }
110 |
111 | return self::$profiles;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Util/AopProxy.php:
--------------------------------------------------------------------------------
1 | addProxy('FileLogger::log', function() {
18 | * echo 'before add log';
19 | * }, 'before');
20 | * $aop->addProxy('FileLogger::log', function() {
21 | * echo 'after add log';
22 | * }, 'after');
23 | * $logger = new FileLogger;
24 | * // not use:
25 | * // $logger->log('message');
26 | * // should:
27 | * $aop->proxy($logger, 'log', ['message']);
28 | * // equal
29 | * $aop->proxy($logger)->call('log', ['message']);
30 | * // equal
31 | * $aop->proxy($logger)->log('message'); // by __call
32 | * // equal
33 | * $aop($logger)->log('message'); // by __invoke
34 | * // equal
35 | * $aop($logger, 'log', ['message']); // by __invoke
36 | */
37 | class AopProxy
38 | {
39 | use AopProxyAwareTrait;
40 |
41 | /**
42 | * @var array
43 | */
44 | protected $proxyMap = [];
45 |
46 | /**
47 | * AopProxy constructor.
48 | * @param array $proxyMap
49 | */
50 | public function __construct(array $proxyMap = [])
51 | {
52 | $this->setProxyMap($proxyMap);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Util/DataProxy.php:
--------------------------------------------------------------------------------
1 | 'handler',
22 | * 'getArticleList' => [ArticleDao::class, 'getArticleList'],
23 | * ]
24 | */
25 | protected $proxies = [];
26 |
27 | public function __construct(array $proxies = [])
28 | {
29 | $this->proxies = $proxies;
30 | }
31 |
32 | /**
33 | * @param string $method
34 | * @param array $args
35 | * @return mixed
36 | */
37 | public function __call($method, array $args)
38 | {
39 | return $this->call($method, $args);
40 | }
41 |
42 | /**
43 | * @param string $name
44 | * @param array $args
45 | * @return mixed
46 | * @throws \RuntimeException
47 | */
48 | public function call(string $name, array $args)
49 | {
50 | if ($this->hasName($name)) {
51 | $handler = $this->proxies[$name];
52 | return $handler(...$args);
53 | }
54 |
55 | throw new \RuntimeException("Called method $name is not exists.");
56 | }
57 |
58 | /**
59 | * @param string $name
60 | * @param callable $callback
61 | */
62 | public function add(string $name, callable $callback): void
63 | {
64 | if (!isset($this->proxies[$name])) {
65 | $this->proxies[$name] = $callback;
66 | }
67 | }
68 |
69 | /**
70 | * @param string $name
71 | * @param callable $callback
72 | */
73 | public function addProxy(string $name, callable $callback): void
74 | {
75 | if (!isset($this->proxies[$name])) {
76 | $this->proxies[$name] = $callback;
77 | }
78 | }
79 |
80 | /**
81 | * @param string $name
82 | * @param callable $callback
83 | */
84 | public function setProxy(string $name, callable $callback): void
85 | {
86 | if (!isset($this->proxies[$name])) {
87 | $this->proxies[$name] = $callback;
88 | }
89 | }
90 |
91 | /**
92 | * @param string $name
93 | * @return bool
94 | */
95 | public function hasName(string $name): bool
96 | {
97 | return isset($this->proxies[$name]);
98 | }
99 |
100 | /**
101 | * @param array $proxies
102 | */
103 | public function addProxies(array $proxies): void
104 | {
105 | foreach ($proxies as $name => $callback) {
106 | $this->addProxy($name, $callback);
107 | }
108 | }
109 |
110 | /**
111 | * @return array
112 | */
113 | public function getProxies(): array
114 | {
115 | return $this->proxies;
116 | }
117 |
118 | /**
119 | * @param array $proxies
120 | */
121 | public function setProxies(array $proxies): void
122 | {
123 | $this->proxies = $proxies;
124 | }
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Util/DataResult.php:
--------------------------------------------------------------------------------
1 | value = $value;
29 | }
30 |
31 | public function get()
32 | {
33 | return $this->value;
34 | }
35 |
36 | /**
37 | * @return mixed
38 | */
39 | public function getValue()
40 | {
41 | return $this->value;
42 | }
43 |
44 | /**
45 | * @param mixed $value
46 | */
47 | public function setValue($value): void
48 | {
49 | $this->value = $value;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Util/DeferredCallable.php:
--------------------------------------------------------------------------------
1 | callable = $callable;
29 | }
30 |
31 | /**
32 | * @param array $args
33 | * @return mixed
34 | * @throws \InvalidArgumentException
35 | */
36 | public function __invoke(...$args)
37 | {
38 | $callable = $this->callable;
39 |
40 | if (\is_callable($callable)) {
41 | return PhpHelper::call($callable, ...$args);
42 | }
43 |
44 | if (\is_string($callable) && class_exists($callable)) {
45 | $obj = new $callable;
46 |
47 | if (method_exists($obj, '__invoke')) {
48 | return $obj(...$args);
49 | }
50 |
51 | throw new \InvalidArgumentException('the defined callable is cannot be called!');
52 | }
53 |
54 | throw new \InvalidArgumentException('the defined callable is error!');
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Util/Pipeline.php:
--------------------------------------------------------------------------------
1 | stages = new \SplObjectStorage;
24 | }
25 |
26 | /**
27 | * {@inheritdoc}
28 | */
29 | public function add(callable $stage)
30 | {
31 | if ($stage instanceof $this) {
32 | $stage->add(function ($payload) {
33 | return $this->invokeStage($payload);
34 | });
35 | }
36 |
37 | $this->stages->attach($stage);
38 |
39 | return $this;
40 | }
41 |
42 | /**
43 | * {@inheritdoc}
44 | */
45 | public function run($payload)
46 | {
47 | $this->stages->rewind();
48 |
49 | return $this->invokeStage($payload);
50 | }
51 |
52 | /**
53 | * {@inheritdoc}
54 | */
55 | public function __invoke($payload)
56 | {
57 | return $this->run($payload);
58 | }
59 |
60 | private function invokeStage($payload)
61 | {
62 | $stage = $this->stages->current();
63 | $this->stages->next();
64 |
65 | if (\is_callable($stage)) {
66 | return $stage($payload, function ($payload) {
67 | return $this->invokeStage($payload);
68 | });
69 | }
70 |
71 | return $payload;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/helper-utils/src/Util/PipelineInterface.php:
--------------------------------------------------------------------------------
1 | $baseDir . '/libs/di/test',
22 | ];
23 |
24 | spl_autoload_register(function ($class) use ($map) {
25 | foreach ($map as $np => $dir) {
26 | if (0 === strpos($class, $np)) {
27 | $path = str_replace('\\', '/', substr($class, strlen($np)));
28 | $file = $dir . "/{$path}.php";
29 |
30 | if (is_file($file)) {
31 | __include_file($file);
32 | }
33 | }
34 | }
35 | });
36 |
37 | function __include_file($file)
38 | {
39 | include $file;
40 | }
41 |
--------------------------------------------------------------------------------
/toolkit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | 'php toolkit',
22 | 'debug' => true,
23 | 'version' => '1.0.0',
24 | 'rootPath' => __DIR__,
25 | ]);
26 | $app->setLogo("
27 | ____ __ ______ ____ _ __
28 | / __ \/ /_ ____ /_ __/___ ____ / / /__(_) /_
29 | / /_/ / __ \/ __ \ / / / __ \/ __ \/ / //_/ / __/
30 | / ____/ / / / /_/ / / / / /_/ / /_/ / / ,< / / /_
31 | /_/ /_/ /_/ .___/ /_/ \____/\____/_/_/|_/_/\__/
32 | /_/
33 | ", 'success');
34 |
35 | // add commands
36 | $app->addController(DevController::class);
37 |
38 | // run
39 | $app->run();
40 |
--------------------------------------------------------------------------------