Commit 53927760 authored by 董先生's avatar 董先生

stock项目创建

parent 827181d3
...@@ -2028,4 +2028,63 @@ function filterNotExistChildren($arr1 =[], $arr2=[], $field){ ...@@ -2028,4 +2028,63 @@ function filterNotExistChildren($arr1 =[], $arr2=[], $field){
return !in_array($item['code'],$oldArray); return !in_array($item['code'],$oldArray);
}); });
return $return; return $return;
}
/*协程方式Curl*/
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/*
* 分析交易所代码
*/
if (!function_exists('toMarket')){
function toMarket($code){
if($code == '000001'){
return 'SZ';
}
if(in_array(substr($code, 0, 1),array('6', '9'))){
return 'SH';
}
if(in_array(substr($code, 0, 1),array('0', '2', '3'))){
return 'SZ';
}
if(in_array(substr($code, 0, 1),array('4', '8'))){
return 'BJ';
}
}
}
/******************************************************************************************/
if(!function_exists('toPinyin')) {
function toPinyin($zh){
// 特殊字符替换(新方法拼音)
$search = [
' ', ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
];
$replace = [
'', '', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
];
$ret = \Yurun\Util\Chinese::toPinyin($zh, \Yurun\Util\Chinese\Pinyin::CONVERT_MODE_PINYIN_FIRST);
$initial = implode('', $ret['pinyinFirst'][0]);
$initial = strtoupper(str_replace($search, $replace, $initial));
preg_match_all('/[a-zA-Z]+/',$initial,$result);
return join('',$result[0]);
}
}
if(!function_exists('get_between')) {
function get_between($input, $start, $end)
{
$substr = substr($input, strlen($start) + strpos($input, $start), (strlen($input) - strpos($input, $end)) * (-1));
return $substr;
}
} }
\ No newline at end of file
...@@ -74,6 +74,7 @@ class Index extends Admin ...@@ -74,6 +74,7 @@ class Index extends Admin
->addColumns([ // 批量添加列 ->addColumns([ // 批量添加列
['title', '股票名'], ['title', '股票名'],
['code', '股票代码'], ['code', '股票代码'],
['market', '市场代码'],
['pinyin', '股票缩写'], ['pinyin', '股票缩写'],
['add_time', '添加时间','datetime'], ['add_time', '添加时间','datetime'],
['quota', '购买总限额(元)'], ['quota', '购买总限额(元)'],
...@@ -270,7 +271,9 @@ class Index extends Admin ...@@ -270,7 +271,9 @@ class Index extends Admin
* @throws \Exception * @throws \Exception
*/ */
public function updateStockTitle(){ public function updateStockTitle(){
$newStocks = $this->getStockList(); // $newStocks = $this->getStockList();
$newStocks = $this->getEastmoneyHKList();
dump($newStocks);die;
$stockListModel = new StockList; $stockListModel = new StockList;
$stocks = []; $stocks = [];
...@@ -302,17 +305,14 @@ class Index extends Admin ...@@ -302,17 +305,14 @@ class Index extends Admin
* @throws \Exception 获取数据异常 * @throws \Exception 获取数据异常
*/ */
private function getStockList($flag){ private function getStockList($flag = ''){
$curl = new Curl(); $curl = new Curl();
$curl->post('https://api.tushare.pro', json_encode([ $curl->post('https://api.tushare.pro', json_encode([
"api_name" => "stock_basic", "api_name" => "stock_basic",
"token" => "7dd8efb1cb02709a28f36dc47a9ea966a2bdc6e3f7419f65c2967b7f", "token" => "7dd8efb1cb02709a28f36dc47a9ea966a2bdc6e3f7419f65c2967b7f",
"params" => "params" =>
array ( array ("list_stauts" => "L",), "fields" => ""])
"list_stauts" => "L", );
),
"fields" => ""
]));
$response = json_decode($curl->response,true); $response = json_decode($curl->response,true);
var_dump($response); var_dump($response);
if($response['code'] !== 0) throw new Exception($response['msg']); if($response['code'] !== 0) throw new Exception($response['msg']);
...@@ -335,6 +335,31 @@ class Index extends Admin ...@@ -335,6 +335,31 @@ class Index extends Admin
},$stocks); },$stocks);
} }
public function getEastmoneyHKList() {
// $url = "https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=2&invt=2&fields=f1,f2,f3,f4,f12,f13,f14&pn=1&fid=f3&po=1&fs=b:DLMK0144&pz=200";
// $url = "https://push2.eastmoney.com/api/qt/clist/get?fltt=2&invt=2&fid=f3&fs=m:201+t:2&fields=f3,f4,f12,f13,f14,f128,f136&np=1&pn=1&po=1&pz=6";
$host = "http://43.push2.eastmoney.com";
$url = $host."/api/qt/clist/get?pn=1&pz=5000&po=1&np=1fltt=2&invt=2&fid=f3&fs=m:128+t:3,m:128+t:4,m:128+t:1,m:128+t:2&fields=f12,f13,f14";
$curl = new Curl();
$curl->get($url);
$output = $curl->response;
// dump($curl->response);die;
$response = json_decode($output,true);
if(!$response['data']['diff']) return false;
//dump($response['data']);exit;
if(isset($response['data']['diff']) && !empty($response['data']['diff'])){
$json['count'] = $response['data']['total'];
foreach ($response['data']['diff'] as $item) {
$cacheData['code'] = trim($item['f12']);
$cacheData['name'] = $item['f14'];
$cacheData['market'] = toMarket($item['f12']);
$cacheData['pinyin'] = strtoupper(toPinYin($item['f14']));
$json['items'][] = $cacheData;
}
}
return $json;
}
//接收数据 //接收数据
public function each($arr){ public function each($arr){
$data['title'] = $arr['name']; $data['title'] = $arr['name'];
......
The MIT License (MIT)
Copyright (c) 2018 宇润
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
# ChineseUtil
PHP 中文工具包,支持汉字转拼音、拼音分词、简繁互转、数字转换、金额数字转换。
由于中文的博大精深,字有多音字,简体字和繁体字也有多种对应。并且本类库返回的所有结果,均为包含所有组合的数组。
本类库字典数据总共收录 73925 个汉字,包括:3955 个简体字,1761 个繁体字,68209 个其它汉字。
## 模式
### 性能模式 (Memory)
使用 SQLite 作为数据载体,一次性加载所有数据到变量,内存占用高(80+ MB),性能最佳。
适合用于运行 Cli 任务。
需要 PDO 和 PDO_SQLITE 扩展支持。
### 通用模式 (SQLite)
使用 SQLite 作为数据载体,每次查询都通过 SQL 查询,内存占用低(100-200 KB),性能中等。
适合用于大部分场景。
需要 PDO 和 PDO_SQLITE 扩展支持。
### 兼容模式 (JSON)
使用精简过的 JSON 数据作为数据载体,一次性加载所有数据到变量,内存占用中(30+ MB),性能差。
> 内存占用量以实际为准,根据版本、扩展等环境的不同,占用的内存容量不一样,上述值为我电脑上的情况,仅供参考。
适合无法使用 PDO 的场景。
由于精简了数据,一些拼音结果需要经过代码计算处理才可以得出,所以性能较差。
### FFI 模式 (FFI)
需要 PHP >= 7.4 并且启用 FFI 扩展,代码全部由 C++ 开发,性能和内存占用都比 PHP 实现的要好。
> FFI 动态库 C++ 代码:<https://github.com/Yurunsoft/chinese-util-cpp>
### Swoole FFI 模式 (SwooleFFI)
需要 PHP >= 7.4 并且启用 FFI、Swoole 扩展,代码全部由 C++ 开发,性能和内存占用都比 PHP 实现的要好。
不会阻塞 PHP 代码所在线程。
---
默认情况下,优先使用通用模式,如果环境不支持 PDO 将采用兼容模式。
你可以在未执行任何初始化或者转换处理之前,设置使用何种模式运行。
```php
// 设为性能模式
Chinese::setMode('Memory');
// 设为通用模式
Chinese::setMode('SQLite');
// 设为兼容模式
Chinese::setMode('JSON');
// 设为 FFI 模式
Chinese::setMode('FFI');
// 设为Swoole FFI 模式
Chinese::setMode('SwooleFFI');
```
无论何种模式,拼音分词所需数据总是从 JSON 数据中加载。
FFI 参数设置:(一般用于自己编译的情况)
```php
use Yurun\Util\Chinese\FFIDriver;
FFIDriver::$library = '.so 文件路径';
FFIDriver::$characterDataPath = '字符数据文件路径';
FFIDriver::$pinyinDataPath = '拼音数据文件路径';
```
## 使用说明
### Composer 直接安装
`composer require yurunsoft/chinese-util`
### Composer 项目配置引入
```
"require": {
"yurunsoft/chinese-util" : "~2.0"
}
```
## 功能
### 汉字转拼音
```php
use \Yurun\Util\Chinese;
use \Yurun\Util\Chinese\Pinyin;
$string = '恭喜發財!123';
echo $string, PHP_EOL;
echo '全拼:', PHP_EOL;
var_dump(Chinese::toPinyin($string, Pinyin::CONVERT_MODE_PINYIN));
echo '首字母:', PHP_EOL;
var_dump(Chinese::toPinyin($string, Pinyin::CONVERT_MODE_PINYIN_FIRST));
echo '读音:', PHP_EOL;
var_dump(Chinese::toPinyin($string, Pinyin::CONVERT_MODE_PINYIN_SOUND));
echo '读音数字:', PHP_EOL;
var_dump(Chinese::toPinyin($string, Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER));
echo '自选返回格式 + 以文本格式返回 + 自定义分隔符:', PHP_EOL;
var_dump(Chinese::toPinyin($string, Pinyin::CONVERT_MODE_PINYIN | Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER, ' '));
echo '所有结果:', PHP_EOL;
var_dump(Chinese::toPinyin($string));
echo '不分割无拼音字符:', PHP_EOL;
var_dump(Chinese::toPinyin($string, Pinyin::CONVERT_MODE_PINYIN, ' ', false));
// 结果太长,请自行运行代码查看
```
### 拼音分词
**结果是字符串:**
```php
use \Yurun\Util\Chinese;
$string2 = 'xianggang';
echo '"', $string2, '"的分词结果:', PHP_EOL;
var_dump(Chinese::splitPinyin($string2));
```
输出结果:
```shell
"xianggang"的分词结果:
array(2) {
[0]=>
string(11) "xiang gang"
[1]=>
string(12) "xi ang gang"
}
```
**结果是数组:**
```php
use \Yurun\Util\Chinese;
$string2 = 'xianggang';
echo '"', $string2, '"的分词结果:', PHP_EOL;
var_dump(Chinese::splitPinyinArray($string2));
```
输出结果:
```shell
"xianggang"的分词结果:
array(2) {
[0]=>
array(2) {
[0]=>
string(5) "xiang"
[1]=>
string(4) "gang"
}
[1]=>
array(3) {
[0]=>
string(2) "xi"
[1]=>
string(3) "ang"
[2]=>
string(4) "gang"
}
}
```
### 简繁互转
```php
use \Yurun\Util\Chinese;
$string3 = '中华人民共和国!恭喜發財!';
echo '"', $string3, '"的简体转换:', PHP_EOL;
var_dump(Chinese::toSimplified($string3));
echo '"', $string3, '"的繁体转换:', PHP_EOL;
var_dump(Chinese::toTraditional($string3));
```
输出结果:
```shell
"中华人民共和国!恭喜發財!"的简体转换:
array(1) {
[0]=>
string(39) "中华人民共和国!恭喜发财!"
}
"中华人民共和国!恭喜發財!"的繁体转换:
array(1) {
[0]=>
string(39) "中華人民共和國!恭喜發財!"
}
```
### 数字转换
```php
use Yurun\Util\Chinese\Number;
function test($number)
{
$chinese = Number::toChinese($number, [
'tenMin' => true, // “一十二” => “十二”
]);
$afterNumber = Number::toNumber($chinese);
echo $number, '=>', $chinese, '=>', $afterNumber, '=>', 0 === bccomp($number, $afterNumber, 20) ? 'true' : 'false', PHP_EOL;
}
test(1.234);
test(-1234567890.666);
test(pi());
```
输出结果:
```shell
1.234=>一点二三四=>1.234=>true
-1234567890.666=>负十二亿三千四百五十六万七千八百九十点六六六=>-1234567890.666=>true
3.1415926535898=>三点一四一五九二六五三五八九八=>3.1415926535898=>true
```
### 金额数字转换
```php
use Yurun\Util\Chinese\Money;
function test($number)
{
$chinese = Money::toChinese($number, [
'tenMin' => true, // “一十二” => “十二”
]);
$afterMoney = Money::toNumber($chinese);
echo $number, '=>', $chinese, '=>', $afterMoney, '=>', 0 === bccomp($number, $afterMoney) ? 'true' : 'false', PHP_EOL;
}
test(1.234);
test(-1234567890.666);
```
输出结果:
```shell
输出结果:
1.234=>壹圆贰角叁分肆厘=>1.234=>true
-1234567890.666=>负壹拾贰亿叁仟肆佰伍拾陆万柒仟捌佰玖拾圆陆角陆分陆厘=>-1234567890.666=>true
```
void init_chinese_util();
\ No newline at end of file
{
"name": "yurunsoft/chinese-util",
"description": "PHP 中文工具包,支持汉字转拼音、拼音分词、简繁互转、数字转换、金额数字转换。",
"type": "library",
"license": "MIT",
"autoload": {
"psr-4": {
"Yurun\\Util\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Yurun\\Util\\ChineseUtil\\Test\\": "tests/unit/"
}
},
"require-dev": {
"phpunit/phpunit": ">=4"
},
"scripts": {
"test": "./vendor/bin/phpunit -c ./tests/phpunit.xml",
"install-test": [
"@composer install",
"@composer test"
]
}
}
This diff is collapsed.
{"sound":{"a":{"ab":"a","tone":0},"ā":{"ab":"a","tone":1},"á":{"ab":"a","tone":2},"ǎ":{"ab":"a","tone":3},"à":{"ab":"a","tone":4},"o":{"ab":"o","tone":0},"ō":{"ab":"o","tone":1},"ó":{"ab":"o","tone":2},"ǒ":{"ab":"o","tone":3},"ò":{"ab":"o","tone":4},"e":{"ab":"e","tone":0},"ē":{"ab":"e","tone":1},"é":{"ab":"e","tone":2},"ě":{"ab":"e","tone":3},"è":{"ab":"e","tone":4},"ī":{"ab":"i","tone":1},"í":{"ab":"i","tone":2},"ǐ":{"ab":"i","tone":3},"ì":{"ab":"i","tone":4},"ū":{"ab":"u","tone":1},"ú":{"ab":"u","tone":2},"ǔ":{"ab":"u","tone":3},"ù":{"ab":"u","tone":4},"ü":{"ab":"v","tone":0},"ǖ":{"ab":"v","tone":1},"ǘ":{"ab":"v","tone":2},"ǚ":{"ab":"v","tone":3},"ǜ":{"ab":"v","tone":4}},"split":{"shengmu":["a","o","e","b","p","m","f","d","t","n","l","g","k","h","j","q","x","r","z","c","s","y","w","zh","ch","sh","er","a","o","e","ai","ei","ao","ou"],"yunmu":["i","u","v","a","o","e","ia","ua","uo","ie","ue","ai","ei","ao","ou","an","en","in","un","ui","uai","iao","uan","ang","eng","ing","ong","iong","iang","uang"],"relation":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"b":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true,"a":{"n":{"py":true},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}}},"o":{"py":true},"u":{"py":true,"n":{"py":true}}},"c":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"n":{"py":true,"g":{"py":true}}},"h":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"d":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true,"a":{"py":true,"n":{"py":true},"o":{"py":true}},"e":{"py":true},"n":{"g":{"py":true}},"u":{"py":true}},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"r":{"py":true}},"f":{"a":{"py":true,"n":{"py":true,"g":{"py":true}}},"e":{"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"a":{"o":{"py":true}}},"o":{"py":true,"u":{"py":true}},"u":{"py":true}},"g":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"h":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"j":{"i":{"py":true,"a":{"py":true,"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"n":{"g":{"py":true}}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"e":{"py":true},"n":{"py":true}}},"k":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"l":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true,"a":{"py":true,"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"u":{"py":true}},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"e":{"py":true},"n":{"py":true},"o":{"py":true}},"v":{"py":true}},"m":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true},"s":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true,"a":{"n":{"py":true},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"u":{"py":true}},"o":{"py":true,"u":{"py":true}},"u":{"py":true}},"n":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true,"a":{"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"u":{"py":true}},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"v":{"py":true,"e":{"py":true}}},"o":{"py":true,"e":{"s":{"py":true}},"u":{"py":true}},"p":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"l":{"py":true}}},"h":{"a":{"s":{"py":true}},"d":{"e":{"n":{"g":{"py":true}}}},"o":{"s":{"py":true}}},"i":{"py":true,"a":{"n":{"py":true},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}}},"o":{"py":true,"u":{"py":true}},"p":{"u":{"n":{"py":true}}},"u":{"py":true}},"q":{"i":{"py":true,"a":{"py":true,"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"n":{"g":{"py":true}}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"e":{"py":true},"n":{"py":true}}},"r":{"a":{"py":true,"m":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"py":true,"n":{"py":true}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"s":{"a":{"py":true,"e":{"n":{"g":{"py":true}}},"i":{"py":true},"l":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"n":{"py":true}}},"h":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"o":{"u":{"py":true}},"u":{"py":true,"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"t":{"a":{"py":true,"e":{"py":true},"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"g":{"py":true}},"u":{"l":{"py":true}}},"i":{"py":true,"a":{"n":{"py":true},"o":{"py":true}},"e":{"py":true},"n":{"g":{"py":true}}},"o":{"n":{"py":true,"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"u":{"u":{"py":true}},"w":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"e":{"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"o":{"py":true},"u":{"py":true}},"x":{"i":{"py":true,"a":{"py":true,"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"n":{"g":{"py":true}}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"e":{"py":true},"n":{"py":true}}},"y":{"a":{"py":true,"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true},"i":{"py":true,"n":{"py":true,"g":{"py":true}}},"o":{"py":true,"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"e":{"py":true},"n":{"py":true}}},"z":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"h":{"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}},"o":{"py":true}},"e":{"py":true,"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"py":true,"i":{"py":true},"n":{"py":true,"g":{"py":true}}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}},"i":{"py":true},"o":{"n":{"g":{"py":true}},"u":{"py":true}},"u":{"py":true,"a":{"n":{"py":true}},"i":{"py":true},"n":{"py":true},"o":{"py":true}}}}}}
\ No newline at end of file
<?php
namespace Yurun\Util;
use Yurun\Util\Chinese\Pinyin;
use Yurun\Util\Chinese\PinyinSplit;
use Yurun\Util\Chinese\SimplifiedAndTraditional;
class Chinese
{
/**
* 是否已初始化.
*
* @var bool
*/
public static $isInited = false;
/**
* 配置数据.
*
* @var array
*/
public static $option = [];
/**
* 中文数据.
*
* @var array
*/
public static $chineseData = [];
/**
* 模式.
*
* @var string
*/
private static $mode;
/**
* 初始化.
*
* @param array $option 初始化配置
*
* @return void
*/
public static function init($option = [])
{
static::$option = $option;
if (null === static::$mode)
{
// 优先使用通用模式,如果环境不支持 PDO 将采用兼容模式。
if (\extension_loaded('pdo_sqlite'))
{
static::setMode('SQLite');
}
else
{
static::setMode('JSON');
}
}
static::$isInited = true;
}
/**
* 将字符串转换为拼音,非中文原样保留.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public static function toPinyin($string, $mode = Pinyin::CONVERT_MODE_FULL, $wordSplit = null, $splitNotPinyinChar = true)
{
if (!static::$isInited)
{
static::init();
}
return Pinyin::toText($string, $mode, $wordSplit, $splitNotPinyinChar);
}
/**
* 拼音分词.
*
* @param string $string
*
* @return array
*/
public static function splitPinyin($string, $wordSplit = ' ')
{
return PinyinSplit::split($string, $wordSplit);
}
/**
* 拼音分词.
*
* @param string $string
*
* @return array
*/
public static function splitPinyinArray($string)
{
return PinyinSplit::split($string, null);
}
/**
* 繁体转简体.
*
* @param string $string
*
* @return array
*/
public static function toSimplified($string)
{
if (!static::$isInited)
{
static::init();
}
return SimplifiedAndTraditional::toSimplified($string);
}
/**
* 简体转繁体.
*
* @param string $string
*
* @return array
*/
public static function toTraditional($string)
{
if (!static::$isInited)
{
static::init();
}
return SimplifiedAndTraditional::toTraditional($string);
}
/**
* 设置模式.
*
* @param string $mode
*
* @return void
*/
public static function setMode($mode)
{
if (static::$mode !== $mode)
{
static::$mode = $mode;
static::$isInited = false;
static::$chineseData = [];
}
}
/**
* 获取模式.
*
* @return string
*/
public static function getMode()
{
return static::$mode;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Money;
interface BaseInterface
{
/**
* 中文金额大写转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text);
/**
* 数字转为中文金额大写.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = []);
}
<?php
namespace Yurun\Util\Chinese\Driver\Money;
use Yurun\Util\Chinese\FFIDriver;
class FFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('FFI');
}
/**
* 中文金额大写转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text)
{
return convert_chinese_to_money($text);
}
/**
* 数字转为中文金额大写.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = [])
{
return convert_money_to_chinese($number);
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Money;
use Yurun\Util\Chinese\Util;
class Memory implements BaseInterface
{
public static $numberMap = [
0 => '零',
1 => '壹',
2 => '贰',
3 => '叁',
4 => '肆',
5 => '伍',
6 => '陆',
7 => '柒',
8 => '捌',
9 => '玖',
'-' => '负',
'.' => '',
];
public static $unitMap = [
'拾',
'佰',
'仟',
'万',
'亿',
];
public static $moneyUnitMap = [
['圆', '元'],
'角',
'分',
'厘',
'毫',
];
/**
* 中文金额大写转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text)
{
$length = mb_strlen($text);
$number = $partNumber = $lastNum = $decimal = 0;
$pom = 1; // 正数或负数,1或-1
$isContain = array_filter(static::$moneyUnitMap[0], function ($moneyUnit) use ($text) {
return strpos($text, $moneyUnit);
});
$flattenMoneyUnitMap = array_reduce(static::$moneyUnitMap, function ($result, $value) {
return array_merge($result, \is_array($value) ? $value : [$value]);
}, []);
$isDecimal = !$isContain;
$scale = \count(static::$moneyUnitMap) - 1;
$lastKey = -1;
for ($i = 0; $i < $length; ++$i)
{
$char = mb_substr($text, $i, 1);
if (0 === $i && static::$numberMap['-'] === $char)
{
$pom = -1;
continue;
}
$key = array_search($char, static::$numberMap);
// 小数
if ($isDecimal)
{
++$i;
$unit = mb_substr($text, $i, 1);
$unitKey = array_search($unit, $flattenMoneyUnitMap) - 1;
if (false === $unitKey)
{
--$i;
$decimal .= $key;
}
else
{
$decimal = bcadd($decimal, bcmul($key, bcpow(10, -($unitKey), $scale), $scale), $scale);
}
}
elseif (false === $key)
{
$key = array_search($char, static::$unitMap);
if (false === $key)
{
$key = array_search($char, $flattenMoneyUnitMap) - 1;
if (false !== $key)
{
$isDecimal = true;
continue;
}
throw new \InvalidArgumentException(sprintf('%s is not a valied chinese number text', $text));
}
// 单位
if ($key > 3)
{
$tNumber = bcpow(10, (($key - 2) * 4));
}
else
{
$tNumber = bcpow(10, $key + 1);
}
if (null === $lastNum)
{
$lastNum = 1;
}
if ($key > 3 || (3 === $key && $partNumber >= 10))
{
if ($key < $lastKey)
{
$number = bcadd($number, bcmul(bcadd($partNumber, $lastNum, $scale), $tNumber, $scale), $scale);
}
else
{
$number = bcmul(bcadd($number, bcadd($partNumber, $lastNum, $scale), $scale), $tNumber, $scale);
}
$partNumber = 0;
$lastNum = null;
$lastKey = $key;
}
else
{
$partNumber = bcadd($partNumber, bcmul($lastNum, $tNumber, $scale), $scale);
$lastNum = 0;
}
}
else
{
$lastNum = $key;
}
}
$result = bcmul(bcadd(bcadd($number, bcadd($partNumber, $lastNum, $scale), $scale), $decimal, $scale), $pom, $scale);
if (false === strpos($result, '.'))
{
return $result;
}
else
{
return rtrim(rtrim($result, '0'), '.');
}
}
/**
* 数字转为中文金额大写.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = [])
{
if (!static::verifyNumber($number))
{
throw new \InvalidArgumentException(sprintf('%s is not a valied number', $number));
}
list($integer, $decimal) = explode('.', $number . '.');
if ($integer < 0)
{
$pom = static::$numberMap['-'];
$integer = abs($integer);
}
else
{
$pom = '';
}
if ($integer > 0)
{
return $pom . static::parseInteger($integer, $options) . static::parseDecimal($decimal, $options);
}
elseif (!$decimal)
{
return static::$numberMap[0] . static::$moneyUnitMap[0][0];
}
else
{
return $pom . static::parseDecimal($decimal, $options);
}
}
/**
* 验证数值
*
* @param string $number
*
* @return bool
*/
public static function verifyNumber($number)
{
return preg_match('/^-?\d+(\.\d+)?$/', $number) > 0;
}
/**
* 处理整数部分.
*
* @param string $number
* @param array $options
*
* @return string
*/
private static function parseInteger($number, $options)
{
// 准备数据,分割为4个数字一组
$length = \strlen($number);
// 同 % 4
$firstItems = $length & 3;
$leftStr = substr($number, $firstItems);
if ('' === $leftStr || false === $leftStr)
{
$split4 = [];
}
else
{
$split4 = str_split($leftStr, 4);
}
if ($firstItems > 0)
{
array_unshift($split4, substr($number, 0, $firstItems));
}
$split4Count = \count($split4);
$unitIndex = ($length - 1) / 4 >> 0;
if (0 === $unitIndex)
{
$unitIndex = -1;
}
else
{
$unitIndex += 2;
}
$result = '';
foreach ($split4 as $i => $item)
{
$index = $unitIndex - $i;
$length = \strlen($item);
$itemResult = '';
$has0 = false;
for ($j = 0; $j < $length; ++$j)
{
if (0 == $item[$j])
{
$has0 = true;
}
else
{
if ($has0)
{
$itemResult .= static::$numberMap[0];
$has0 = false;
}
$itemResult .= static::$numberMap[$item[$j]];
if (isset(static::$unitMap[$length - $j - 2]))
{
$itemResult .= static::$unitMap[$length - $j - 2];
}
}
}
if ($has0)
{
$itemResult .= static::$numberMap[0];
}
if ('' === $itemResult)
{
if (isset(static::$unitMap[$index]))
{
if ($index > 3)
{
$result .= static::$unitMap[$index];
}
}
elseif ('0' != $item)
{
$result .= isset(static::$unitMap[$index + 1]) ? static::$unitMap[$index + 1] : str_repeat(static::$unitMap[3], max($index - 3, 0));
}
}
else
{
if ($i !== $split4Count - 1 && isset(static::$unitMap[$index]))
{
$unit = static::$unitMap[$index];
}
else
{
$unit = $index > 4 ? static::$unitMap[3] : '';
}
$result .= $itemResult . $unit;
}
}
if ('' !== $result)
{
$result = Util::mbRtrim($result, static::$numberMap[0]);
if ('' !== $result)
{
$result .= static::$moneyUnitMap[0][0];
}
}
return $result;
}
/**
* 处理小数部分.
*
* @param string $number
* @param array $options
*
* @return string
*/
private static function parseDecimal($number, $options)
{
if ('' === $number)
{
return '';
}
$result = '';
$length = \strlen($number);
for ($i = 0; $i < $length; ++$i)
{
if (0 == $number[$i])
{
$result .= static::$numberMap[$number[$i]];
}
else
{
$result .= static::$numberMap[$number[$i]] . (isset(static::$moneyUnitMap[$i + 1]) ? static::$moneyUnitMap[$i + 1] : '');
}
}
$ltrimResult = Util::mbLtrim($result, static::$numberMap[0]);
return '' === $ltrimResult || $ltrimResult === $result ? $ltrimResult : (static::$numberMap[0] . $ltrimResult);
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Money;
use Yurun\Util\Chinese\FFIDriver;
class SwooleFFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('SwooleFFI');
}
/**
* 中文金额大写转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text)
{
return swoole_convert_chinese_to_money($text);
}
/**
* 数字转为中文金额大写.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = [])
{
return swoole_convert_money_to_chinese($number);
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Number;
interface BaseInterface
{
/**
* 中文口语化数字转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text);
/**
* 数字转为中文口语化数字.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = []);
}
<?php
namespace Yurun\Util\Chinese\Driver\Number;
use Yurun\Util\Chinese\FFIDriver;
class FFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('FFI');
}
/**
* 中文口语化数字转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text)
{
return convert_chinese_to_number($text);
}
/**
* 数字转为中文口语化数字.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = [])
{
return convert_number_to_chinese($number, isset($options['tenMin']) ? $options['tenMin'] : false);
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Number;
class Memory implements BaseInterface
{
public static $numberMap = [
0 => '零',
1 => '一',
2 => '二',
3 => '三',
4 => '四',
5 => '五',
6 => '六',
7 => '七',
8 => '八',
9 => '九',
'-' => '负',
'.' => '点',
];
public static $unitMap = [
'十',
'百',
'千',
'万',
'亿',
'兆',
'京',
];
/**
* 中文口语化数字转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text)
{
$length = mb_strlen($text);
$number = $partNumber = 0;
$pom = 1; // 正数或负数,1或-1
$lastNum = 0;
$isDecimal = false;
$decimal = '';
for ($i = 0; $i < $length; ++$i)
{
$char = mb_substr($text, $i, 1);
if (0 === $i && static::$numberMap['-'] === $char)
{
$pom = -1;
continue;
}
if (static::$numberMap['.'] === $char)
{
$isDecimal = true;
continue;
}
$key = array_search($char, static::$numberMap);
if (false === $key)
{
$key = array_search($char, static::$unitMap);
if (false === $key)
{
throw new \InvalidArgumentException(sprintf('%s is not a valied chinese number text', $text));
}
if (0 === $key && 0 === $lastNum)
{
$lastNum = 1;
}
// 单位
if ($key >= 3)
{
$partNumber += $lastNum;
$number += $partNumber * bcpow(10, (($key - 3) * 4) + 4);
$partNumber = 0;
}
else
{
$partNumber += $lastNum * bcpow(10, $key + 1);
}
$lastNum = 0;
}
else
{
// 数字
if ($isDecimal)
{
$decimal .= $key;
}
else
{
$lastNum = $key;
}
}
}
return bcmul(bcadd($number, bcadd($partNumber, $lastNum)), $pom) . ($isDecimal ? ('.' . $decimal) : '');
}
/**
* 数字转为中文口语化数字.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = [])
{
if (!static::verifyNumber($number))
{
throw new \InvalidArgumentException(sprintf('%s is not a valied number', $number));
}
list($integer, $decimal) = explode('.', $number . '.');
if ($integer < 0)
{
$pom = static::$numberMap['-'];
$integer = abs($integer);
}
else
{
$pom = '';
}
$integerPart = static::parseInteger($integer, $options);
if ('' === $integerPart)
{
$integerPart = static::$numberMap[0];
}
$decimalPart = static::parseDecimal($decimal, $options);
return $pom . $integerPart . $decimalPart;
}
/**
* 验证数值
*
* @param string $number
*
* @return bool
*/
public static function verifyNumber($number)
{
return preg_match('/^-?\d+(\.\d+)?$/', $number) > 0;
}
/**
* 处理整数部分.
*
* @param string $number
* @param array $options
*
* @return string
*/
private static function parseInteger($number, $options)
{
// “一十二” => “十二”
$tenMin = isset($options['tenMin']) ? $options['tenMin'] : false;
// 准备数据,分割为4个数字一组
$length = \strlen($number);
// 同 % 4
$firstItems = $length & 3;
$leftStr = substr($number, $firstItems);
if ('' === $leftStr || false === $leftStr)
{
$split4 = [];
}
else
{
$split4 = str_split($leftStr, 4);
}
if ($firstItems > 0)
{
array_unshift($split4, substr($number, 0, $firstItems));
}
$split4Count = \count($split4);
$unitIndex = ($length - 1) / 4 >> 0;
if (0 === $unitIndex)
{
$unitIndex = -1;
}
else
{
$unitIndex += 2;
}
$result = '';
foreach ($split4 as $i => $item)
{
$index = $unitIndex - $i;
$length = \strlen($item);
$itemResult = '';
$has0 = false;
for ($j = 0; $j < $length; ++$j)
{
if (0 == $item[$j])
{
$has0 = true;
}
else
{
if ($has0)
{
$itemResult .= static::$numberMap[0];
$has0 = false;
}
if (!($tenMin && 2 === $length && 0 === $j && 1 == $item[$j]))
{
$itemResult .= static::$numberMap[$item[$j]];
}
if (0 != $item[$j])
{
$itemResult .= (isset(static::$unitMap[$length - $j - 2]) ? static::$unitMap[$length - $j - 2] : '');
}
}
}
if ('' != $itemResult)
{
$result .= $itemResult . (($i != $split4Count - 1 && isset(static::$unitMap[$index])) ? static::$unitMap[$index] : '');
}
}
return $result;
}
/**
* 处理小数部分.
*
* @param string $number
* @param array $options
*
* @return string
*/
private static function parseDecimal($number, $options)
{
if ('' === $number)
{
return '';
}
$result = static::$numberMap['.'];
$length = \strlen($number);
for ($i = 0; $i < $length; ++$i)
{
$result .= static::$numberMap[$number[$i]];
}
return $result;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Number;
use Yurun\Util\Chinese\FFIDriver;
class SwooleFFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('SwooleFFI');
}
/**
* 中文口语化数字转数字.
*
* @param string $text
*
* @return string
*/
public function toNumber($text)
{
return swoole_convert_chinese_to_number($text);
}
/**
* 数字转为中文口语化数字.
*
* @param string $number
* @param array $options
*
* @return string
*/
public function toChinese($number, $options = [])
{
return swoole_convert_number_to_chinese($number, isset($options['tenMin']) ? $options['tenMin'] : false);
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese\Pinyin;
abstract class Base implements BaseInterface
{
/**
* 把字符串转为拼音结果,返回的数组成员为字符串.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public function convert($string, $mode = Pinyin::CONVERT_MODE_FULL, $wordSplit = null, $splitNotPinyinChar = true)
{
return $this->parseResult($this->getResult($string, $splitNotPinyinChar), $mode, $wordSplit);
}
/**
* 结果去重.
*
* @param array $array
*
* @return array
*/
protected function uniqueResult($array)
{
$newArray = array_map('unserialize', array_unique(array_map('serialize', $array)));
if ($array !== $newArray)
{
$newArray = array_values($newArray);
}
return $newArray;
}
/**
* 处理结果.
*
* @param array $list
* @param int $mode
* @param string $wordSplit
*
* @return void
*/
abstract protected function parseResult($list, $mode, $wordSplit);
/**
* 把字符串转为拼音数组结果.
*
* @param string $string
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
abstract protected function getResult($string, $splitNotPinyinChar = true);
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese\Pinyin;
interface BaseInterface
{
/**
* 把字符串转为拼音结果,返回的数组成员为字符串.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public function convert($string, $mode = Pinyin::CONVERT_MODE_FULL, $wordSplit = null, $splitNotPinyinChar = true);
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese\FFIDriver;
use Yurun\Util\Chinese\Pinyin;
class FFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('FFI');
}
/**
* 把字符串转为拼音结果,返回的数组成员为字符串.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public function convert($string, $mode = Pinyin::CONVERT_MODE_FULL, $wordSplit = null, $splitNotPinyinChar = true)
{
if (null === $wordSplit)
{
return convert_to_pinyin_array($string, $mode, $splitNotPinyinChar);
}
else
{
return convert_to_pinyin_string($string, $mode, $splitNotPinyinChar, $wordSplit);
}
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese;
use Yurun\Util\Chinese\JSONIndex;
use Yurun\Util\Chinese\Pinyin;
class JSON extends Base
{
use \Yurun\Util\Chinese\Traits\JSONInit;
public function __construct()
{
$this->loadChars();
$this->loadPinyinSound();
}
/**
* 处理结果.
*
* @param array $list
* @param int $mode
* @param string $wordSplit
*
* @return void
*/
protected function parseResult($list, $mode, $wordSplit)
{
$pinyinSounds = [[]];
$oldResultCount = null;
foreach ($list as $item)
{
$item[JSONIndex::INDEX_PINYIN] = explode(',', $item[JSONIndex::INDEX_PINYIN]);
// 拼音和拼音首字母
$count = \count($item[JSONIndex::INDEX_PINYIN]);
$oldResultCount = \count($pinyinSounds);
$oldResultPinyin = $pinyinSounds;
for ($i = 0; $i < $count - 1; ++$i)
{
$pinyinSounds = array_merge($pinyinSounds, $oldResultPinyin);
}
foreach ($item[JSONIndex::INDEX_PINYIN] as $index => $pinyin)
{
for ($i = 0; $i < $oldResultCount; ++$i)
{
$j = $index * $oldResultCount + $i;
$pinyinSounds[$j][] = $pinyin;
}
}
}
$isPinyin = (($mode & Pinyin::CONVERT_MODE_PINYIN) === Pinyin::CONVERT_MODE_PINYIN);
$isPinyinSound = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND) === Pinyin::CONVERT_MODE_PINYIN_SOUND);
$isPinyinSoundNumber = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER) === Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER);
$isPinyinFirst = (($mode & Pinyin::CONVERT_MODE_PINYIN_FIRST) === Pinyin::CONVERT_MODE_PINYIN_FIRST);
$result = [];
if ($isPinyin)
{
$result['pinyin'] = [];
}
if ($isPinyinSound)
{
$result['pinyinSound'] = [[]];
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = [];
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = [];
}
if ((($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND) === Pinyin::CONVERT_MODE_PINYIN_SOUND))
{
if (null === $wordSplit)
{
$result['pinyinSound'] = $pinyinSounds;
}
else
{
foreach ($pinyinSounds as $pinyinSoundItem)
{
$result['pinyinSound'][] = implode($wordSplit, $pinyinSoundItem);
}
}
}
foreach ($pinyinSounds as $pinyinSound)
{
$itemResult = $this->parseSoundItem($pinyinSound, $mode);
if ($isPinyin)
{
$result['pinyin'][] = null === $wordSplit ? $itemResult['pinyin'] : implode($wordSplit, $itemResult['pinyin']);
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'][] = null === $wordSplit ? $itemResult['pinyinSoundNumber'] : implode($wordSplit, $itemResult['pinyinSoundNumber']);
}
if ($isPinyinFirst)
{
$result['pinyinFirst'][] = null === $wordSplit ? $itemResult['pinyinFirst'] : implode($wordSplit, $itemResult['pinyinFirst']);
}
}
if ($isPinyin)
{
$result['pinyin'] = $this->uniqueResult($result['pinyin']);
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = $this->uniqueResult($result['pinyinSoundNumber']);
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = $this->uniqueResult($result['pinyinFirst']);
}
return $result;
}
/**
* 把字符串转为拼音数组结果.
*
* @param string $string
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
protected function getResult($string, $splitNotPinyinChar = true)
{
$len = mb_strlen($string, 'UTF-8');
$list = [];
$noResultItem = null;
for ($i = 0; $i < $len; ++$i)
{
$word = mb_substr($string, $i, 1, 'UTF-8');
if (isset(Chinese::$chineseData['chars'][$word]))
{
if (!$splitNotPinyinChar && null !== $noResultItem)
{
$list[] = $noResultItem;
$noResultItem = null;
}
$list[] = Chinese::$chineseData['chars'][$word];
}
else
{
if ($splitNotPinyinChar)
{
$list[] = [
JSONIndex::INDEX_PINYIN => $word,
];
}
else
{
if (null === $noResultItem)
{
$noResultItem[JSONIndex::INDEX_PINYIN] = '';
}
$noResultItem[JSONIndex::INDEX_PINYIN] .= $word;
}
}
}
if (!$splitNotPinyinChar && null !== $noResultItem)
{
$list[] = $noResultItem;
}
return $list;
}
private function parseSoundItem($array, $mode)
{
static $pattern, $splitSeparator;
if (null === $pattern)
{
$pattern = '/([' . implode('', array_keys(Chinese::$chineseData['pinyinSound'])) . '])/u';
}
if (null === $splitSeparator)
{
$splitSeparator = '/' . uniqid('', true) . '/';
}
$isPinyin = (($mode & Pinyin::CONVERT_MODE_PINYIN) === Pinyin::CONVERT_MODE_PINYIN);
$isPinyinSoundNumber = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER) === Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER);
$isPinyinFirst = (($mode & Pinyin::CONVERT_MODE_PINYIN_FIRST) === Pinyin::CONVERT_MODE_PINYIN_FIRST);
$result = [];
if ($isPinyin)
{
$result['pinyin'] = [];
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = [];
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = [];
}
if ($isPinyin)
{
$result['pinyin'] = explode($splitSeparator, preg_replace_callback(
$pattern,
function ($matches) {
return Chinese::$chineseData['pinyinSound'][$matches[0]]['ab'];
},
implode($splitSeparator, $array)
));
}
foreach ($array as $pinyinSoundItem)
{
if ($isPinyinSoundNumber)
{
$tone = null;
$str = preg_replace_callback(
$pattern,
function ($matches) use (&$tone) {
$tone = Chinese::$chineseData['pinyinSound'][$matches[0]]['tone'];
return Chinese::$chineseData['pinyinSound'][$matches[0]]['ab'];
},
$pinyinSoundItem,
1
);
if (null === $tone)
{
$result['pinyinSoundNumber'][] = $str;
}
else
{
$result['pinyinSoundNumber'][] = $str . $tone;
}
}
if ($isPinyinFirst)
{
$result['pinyinFirst'][] = mb_substr(preg_replace_callback(
$pattern,
function ($matches) {
return Chinese::$chineseData['pinyinSound'][$matches[0]]['ab'];
},
$pinyinSoundItem,
1
), 0, 1);
}
}
return $result;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese;
use Yurun\Util\Chinese\Pinyin;
class Memory extends Base
{
use \Yurun\Util\Chinese\Traits\MemoryInit;
public function __construct()
{
$this->initData();
}
/**
* 处理结果.
*
* @param array $list
* @param int $mode
* @param string $wordSplit
*
* @return void
*/
public function parseResult($list, $mode, $wordSplit)
{
$isPinyin = (($mode & Pinyin::CONVERT_MODE_PINYIN) === Pinyin::CONVERT_MODE_PINYIN);
$isPinyinSound = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND) === Pinyin::CONVERT_MODE_PINYIN_SOUND);
$isPinyinSoundNumber = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER) === Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER);
$isPinyinFirst = (($mode & Pinyin::CONVERT_MODE_PINYIN_FIRST) === Pinyin::CONVERT_MODE_PINYIN_FIRST);
$result = [];
if ($isPinyin)
{
$result['pinyin'] = [[]];
}
if ($isPinyinSound)
{
$result['pinyinSound'] = [[]];
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = [[]];
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = [[]];
}
foreach ($list as $item)
{
// 拼音和拼音首字母
$count = \count($item['pinyin']);
if ($isPinyin || $isPinyinFirst)
{
$oldResultCount = null;
if ($isPinyin)
{
$oldResultCount = \count($result['pinyin']);
$oldResultPinyin = $result['pinyin'];
}
if ($isPinyinFirst)
{
if (null === $oldResultCount)
{
$oldResultCount = \count($result['pinyinFirst']);
}
$oldResultPinyinFirst = $result['pinyinFirst'];
}
for ($i = 0; $i < $count - 1; ++$i)
{
if ($isPinyin)
{
$result['pinyin'] = array_merge($result['pinyin'], $oldResultPinyin);
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = array_merge($result['pinyinFirst'], $oldResultPinyinFirst);
}
}
foreach ($item['pinyin'] as $index => $pinyin)
{
for ($i = 0; $i < $oldResultCount; ++$i)
{
$j = $index * $oldResultCount + $i;
if ($isPinyin)
{
$result['pinyin'][$j][] = $pinyin;
}
if ($isPinyinFirst)
{
$result['pinyinFirst'][$j][] = mb_substr($pinyin, 0, 1);
}
}
}
}
// 拼音读音
if ($isPinyinSound || $isPinyinSoundNumber)
{
$oldResultCount = null;
if (isset($item['pinyinSound']))
{
$count = \count($item['pinyinSound']);
}
else
{
$count = 0;
}
if ($isPinyinSound)
{
$oldResultCount = \count($result['pinyinSound']);
$oldResultPinyinSound = $result['pinyinSound'];
}
if ($isPinyinSoundNumber)
{
if (null === $oldResultCount)
{
$oldResultCount = \count($result['pinyinSoundNumber']);
}
$oldResultPinyinSoundNumber = $result['pinyinSoundNumber'];
}
for ($i = 0; $i < $count - 1; ++$i)
{
if ($isPinyinSound)
{
$result['pinyinSound'] = array_merge($result['pinyinSound'], $oldResultPinyinSound);
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = array_merge($result['pinyinSoundNumber'], $oldResultPinyinSoundNumber);
}
}
for ($index = 0; $index < $count; ++$index)
{
for ($i = 0; $i < $oldResultCount; ++$i)
{
$j = $index * $oldResultCount + $i;
if ($isPinyinSound)
{
$result['pinyinSound'][$j][] = $item['pinyinSound'][$index];
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'][$j][] = $item['pinyinSoundNumber'][$index];
}
}
}
}
}
if (null !== $wordSplit)
{
if ($isPinyin)
{
foreach ($result['pinyin'] as $index => $value)
{
$result['pinyin'][$index] = implode($wordSplit, $value);
}
}
if ($isPinyinSound)
{
foreach ($result['pinyinSound'] as $index => $value)
{
$result['pinyinSound'][$index] = implode($wordSplit, $value);
}
}
if ($isPinyinSoundNumber)
{
foreach ($result['pinyinSoundNumber'] as $index => $value)
{
$result['pinyinSoundNumber'][$index] = implode($wordSplit, $value);
}
}
if ($isPinyinFirst)
{
foreach ($result['pinyinFirst'] as $index => $value)
{
$result['pinyinFirst'][$index] = implode($wordSplit, $value);
}
}
}
if ($isPinyin)
{
$result['pinyin'] = $this->uniqueResult($result['pinyin']);
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = $this->uniqueResult($result['pinyinSoundNumber']);
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = $this->uniqueResult($result['pinyinFirst']);
}
return $result;
}
/**
* 把字符串转为拼音数组结果.
*
* @param string $string
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public function getResult($string, $splitNotPinyinChar = true)
{
$len = mb_strlen($string, 'UTF-8');
$list = [];
$noResultItem = null;
for ($i = 0; $i < $len; ++$i)
{
$word = mb_substr($string, $i, 1, 'UTF-8');
if (isset(Chinese::$chineseData['chars'][$word]))
{
if (!$splitNotPinyinChar && null !== $noResultItem)
{
$list[] = $noResultItem;
$noResultItem = null;
}
$list[] = Chinese::$chineseData['chars'][$word];
}
else
{
if ($splitNotPinyinChar)
{
$list[] = [
'pinyin' => [$word],
'pinyinSound' => [$word],
'pinyinSound' => [$word],
'pinyinSoundNumber' => [$word],
];
}
else
{
if (null === $noResultItem)
{
$noResultItem['pinyin'][0] = '';
}
$noResultItem['pinyin'][0] .= $word;
}
}
}
if (!$splitNotPinyinChar && null !== $noResultItem)
{
$list[] = $noResultItem;
}
return $list;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese\Pinyin;
use Yurun\Util\Chinese\SQLiteData;
class SQLite extends Base
{
public function __construct()
{
SQLiteData::init();
}
/**
* 处理结果.
*
* @param array $list
* @param int $mode
* @param string $wordSplit
*
* @return void
*/
protected function parseResult($list, $mode, $wordSplit)
{
$isPinyin = (($mode & Pinyin::CONVERT_MODE_PINYIN) === Pinyin::CONVERT_MODE_PINYIN);
$isPinyinSound = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND) === Pinyin::CONVERT_MODE_PINYIN_SOUND);
$isPinyinSoundNumber = (($mode & Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER) === Pinyin::CONVERT_MODE_PINYIN_SOUND_NUMBER);
$isPinyinFirst = (($mode & Pinyin::CONVERT_MODE_PINYIN_FIRST) === Pinyin::CONVERT_MODE_PINYIN_FIRST);
$result = [];
if ($isPinyin)
{
$result['pinyin'] = [[]];
}
if ($isPinyinSound)
{
$result['pinyinSound'] = [[]];
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = [[]];
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = [[]];
}
foreach ($list as $item)
{
// 拼音和拼音首字母
$count = \count($item['pinyin']);
if ($isPinyin || $isPinyinFirst)
{
$oldResultCount = null;
if ($isPinyin)
{
$oldResultCount = \count($result['pinyin']);
$oldResultPinyin = $result['pinyin'];
}
if ($isPinyinFirst)
{
if (null === $oldResultCount)
{
$oldResultCount = \count($result['pinyinFirst']);
}
$oldResultPinyinFirst = $result['pinyinFirst'];
}
for ($i = 0; $i < $count - 1; ++$i)
{
if ($isPinyin)
{
$result['pinyin'] = array_merge($result['pinyin'], $oldResultPinyin);
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = array_merge($result['pinyinFirst'], $oldResultPinyinFirst);
}
}
foreach ($item['pinyin'] as $index => $pinyin)
{
for ($i = 0; $i < $oldResultCount; ++$i)
{
$j = $index * $oldResultCount + $i;
if ($isPinyin)
{
$result['pinyin'][$j][] = $pinyin;
}
if ($isPinyinFirst)
{
$result['pinyinFirst'][$j][] = mb_substr($pinyin, 0, 1);
}
}
}
}
// 拼音读音
if ($isPinyinSound || $isPinyinSoundNumber)
{
$oldResultCount = null;
if (isset($item['pinyinSound']))
{
$count = \count($item['pinyinSound']);
}
else
{
$count = 0;
}
if ($isPinyinSound)
{
$oldResultCount = \count($result['pinyinSound']);
$oldResultPinyinSound = $result['pinyinSound'];
}
if ($isPinyinSoundNumber)
{
if (null === $oldResultCount)
{
$oldResultCount = \count($result['pinyinSoundNumber']);
}
$oldResultPinyinSoundNumber = $result['pinyinSoundNumber'];
}
for ($i = 0; $i < $count - 1; ++$i)
{
if ($isPinyinSound)
{
$result['pinyinSound'] = array_merge($result['pinyinSound'], $oldResultPinyinSound);
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = array_merge($result['pinyinSoundNumber'], $oldResultPinyinSoundNumber);
}
}
for ($index = 0; $index < $count; ++$index)
{
for ($i = 0; $i < $oldResultCount; ++$i)
{
$j = $index * $oldResultCount + $i;
if ($isPinyinSound)
{
$result['pinyinSound'][$j][] = $item['pinyinSound'][$index];
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'][$j][] = $item['pinyinSoundNumber'][$index];
}
}
}
}
}
if (null !== $wordSplit)
{
if ($isPinyin)
{
foreach ($result['pinyin'] as $index => $value)
{
$result['pinyin'][$index] = implode($wordSplit, $value);
}
}
if ($isPinyinSound)
{
foreach ($result['pinyinSound'] as $index => $value)
{
$result['pinyinSound'][$index] = implode($wordSplit, $value);
}
}
if ($isPinyinSoundNumber)
{
foreach ($result['pinyinSoundNumber'] as $index => $value)
{
$result['pinyinSoundNumber'][$index] = implode($wordSplit, $value);
}
}
if ($isPinyinFirst)
{
foreach ($result['pinyinFirst'] as $index => $value)
{
$result['pinyinFirst'][$index] = implode($wordSplit, $value);
}
}
}
if ($isPinyin)
{
$result['pinyin'] = $this->uniqueResult($result['pinyin']);
}
if ($isPinyinSoundNumber)
{
$result['pinyinSoundNumber'] = $this->uniqueResult($result['pinyinSoundNumber']);
}
if ($isPinyinFirst)
{
$result['pinyinFirst'] = $this->uniqueResult($result['pinyinFirst']);
}
return $result;
}
/**
* 把字符串转为拼音数组结果.
*
* @param string $string
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
protected function getResult($string, $splitNotPinyinChar = true)
{
$len = mb_strlen($string, 'UTF-8');
$list = [];
$noResultItem = null;
for ($i = 0; $i < $len; ++$i)
{
$word = mb_substr($string, $i, 1, 'UTF-8');
$data = SQLiteData::getData($word);
if (isset($data['char']))
{
if (!$splitNotPinyinChar && null !== $noResultItem)
{
$list[] = $noResultItem;
$noResultItem = null;
}
$list[] = $data;
}
else
{
if ($splitNotPinyinChar)
{
$list[] = [
'pinyin' => [$word],
'pinyinSound' => [$word],
'pinyinSound' => [$word],
'pinyinSoundNumber' => [$word],
];
}
else
{
if (null === $noResultItem)
{
$noResultItem['pinyin'][0] = '';
}
$noResultItem['pinyin'][0] .= $word;
}
}
}
if (!$splitNotPinyinChar && null !== $noResultItem)
{
$list[] = $noResultItem;
}
return $list;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\Pinyin;
use Yurun\Util\Chinese\FFIDriver;
use Yurun\Util\Chinese\Pinyin;
class SwooleFFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('SwooleFFI');
}
/**
* 把字符串转为拼音结果,返回的数组成员为字符串.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public function convert($string, $mode = Pinyin::CONVERT_MODE_FULL, $wordSplit = null, $splitNotPinyinChar = true)
{
if (null === $wordSplit)
{
return swoole_convert_to_pinyin_array($string, $mode, $splitNotPinyinChar);
}
else
{
return swoole_convert_to_pinyin_string($string, $mode, $splitNotPinyinChar, $wordSplit);
}
}
}
<?php
namespace Yurun\Util\Chinese\Driver\PinyinSplit;
interface BaseInterface
{
/**
* 拼音分词.
*
* @param string $text
* @param string|null $wordSplit
*
* @return array
*/
public function split($text, $wordSplit = ' ');
}
<?php
namespace Yurun\Util\Chinese\Driver\PinyinSplit;
use Yurun\Util\Chinese\FFIDriver;
class FFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('FFI');
}
/**
* 拼音分词.
*
* @param string $text
* @param string|null $wordSplit
*
* @return array
*/
public function split($text, $wordSplit = ' ')
{
if (null === $wordSplit)
{
return split_pinyin_array($text);
}
else
{
return split_pinyin_string($text, $wordSplit);
}
}
}
<?php
namespace Yurun\Util\Chinese\Driver\PinyinSplit;
use Yurun\Util\Chinese;
class Memory implements BaseInterface
{
public function __construct()
{
// 拼音分词数据加载
if (!isset(Chinese::$option['pinyinSplitData']))
{
if (!empty(Chinese::$option['pinyinSplitData']))
{
Chinese::$chineseData['pinyin'] = Chinese::$option['pinyinSplitData'];
}
elseif (empty(Chinese::$option['pinyinSplitDataPath']))
{
Chinese::$chineseData['pinyin'] = json_decode(file_get_contents(\dirname(\dirname(\dirname(\dirname(__DIR__)))) . '/data/pinyinData.json'), true)['split'];
}
else
{
Chinese::$chineseData['pinyin'] = json_decode(file_get_contents(Chinese::$option['pinyinSplitDataPath']), true)['split'];
}
}
}
/**
* 拼音分词.
*
* @param string $text
* @param string|null $wordSplit
*
* @return array
*/
public function split($text, $wordSplit = ' ')
{
if ('' === $text)
{
return [];
}
$this->parseBlock($text, $beginMaps, $endMaps, $length);
if (!isset($beginMaps[0]))
{
throw new \RuntimeException('Data error');
}
$result = [];
$stacks = [
[
'index' => 0,
'result' => [[]],
],
];
while ($stacks)
{
$stack = array_pop($stacks);
$index = $stack['index'];
if (!isset($beginMaps[$index]))
{
throw new \RuntimeException('Index value error');
}
foreach ($beginMaps[$index] as $item)
{
if (!$item['isPinyin'] && isset($endMaps[$index]))
{
continue;
}
$itemNextIndex = $item['end'] + 1;
if (!isset($beginMaps[$itemNextIndex]) && $itemNextIndex < $length - 1)
{
continue;
}
$itemResult = [];
foreach ($stack['result'] as $resultItem)
{
$resultItem[] = $item['text'];
$itemResult[] = $resultItem;
}
if ($itemNextIndex < $length)
{
$stacks[] = [
'index' => $itemNextIndex,
'result' => $itemResult,
];
}
else
{
$result = array_merge($result, $itemResult);
}
}
}
if (null !== $wordSplit)
{
foreach ($result as &$item)
{
$item = implode($wordSplit, $item);
}
}
return $result;
}
private function parseBlock($text, &$beginMaps, &$endMaps, &$length)
{
// 把每个连续的拼音连成块
$blocks = preg_split('/([^a-zA-Z]+)/', $text, null, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
$hasNoPinyinChars = isset($blocks[1]);
if ($hasNoPinyinChars)
{
$oddIsPinyin = preg_match('/^([a-zA-Z]+)$/', $blocks[0]) > 0;
}
$relationList = Chinese::$chineseData['pinyin']['relation'];
$length = 0;
$beginMaps = $endMaps = [];
// 遍历每个块
foreach ($blocks as $blockIndex => $block)
{
$blockLength = mb_strlen($block, 'UTF-8');
if ($hasNoPinyinChars)
{
$blockIndexIsOdd = (1 === ($blockIndex & 1));
if ($oddIsPinyin === $blockIndexIsOdd)
{
$begin = $length;
$length += $blockLength;
$beginMaps[$begin][] = [
'text' => $block,
'isPinyin' => false,
'relation' => null,
'begin' => $begin,
'end' => $length - 1,
];
continue;
}
}
$tempBlockResults = [];
// 遍历每个字
for ($i = 0; $i < $blockLength; ++$i)
{
$character = mb_substr($block, $i, 1, 'UTF-8');
foreach (array_keys($tempBlockResults) as $j)
{
$tempBlockResultItem = &$tempBlockResults[$j];
$relation = &$tempBlockResultItem['relation'];
if (isset($relation[$character]))
{
if ($tempBlockResultItem['isPinyin'])
{
$tempBlockResultItem2 = $tempBlockResultItem;
$tempBlockResultItem2['end'] = $end = $length + $i - 1;
unset($tempBlockResultItem2['relation']);
$beginMaps[$tempBlockResultItem2['begin']][] = $tempBlockResultItem2;
if ($tempBlockResultItem2['isPinyin'])
{
$endMaps[$end] = true;
}
}
$tempBlockResultItem['isPinyin'] = isset($relation[$character]['py']);
$tempBlockResultItem['text'] .= $character;
$tempBlockResultItem['relation'] = &$relation[$character];
}
else
{
// 保存
$tempBlockResultItem['end'] = $end = $length + $i - 1;
unset($tempBlockResultItem['relation']);
$beginMaps[$tempBlockResultItem['begin']][] = $tempBlockResultItem;
if ($tempBlockResultItem['isPinyin'])
{
$endMaps[$end] = true;
}
unset($tempBlockResults[$j]);
}
unset($tempBlockResultItem, $relation);
}
$tempBlockResults[] = [
'text' => $character,
'isPinyin' => isset($relationList[$character]['py']),
'relation' => &$relationList[$character],
'begin' => $length + $i,
];
}
if ($tempBlockResults)
{
foreach ($tempBlockResults as $tempBlockResultItem)
{
// 保存
$tempBlockResultItem['end'] = $end = $length + $i - 1;
unset($tempBlockResultItem['relation']);
$beginMaps[$tempBlockResultItem['begin']][] = $tempBlockResultItem;
if ($tempBlockResultItem['isPinyin'])
{
$endMaps[$end] = true;
}
}
}
$length += $blockLength;
}
}
}
<?php
namespace Yurun\Util\Chinese\Driver\PinyinSplit;
use Yurun\Util\Chinese\FFIDriver;
class SwooleFFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('SwooleFFI');
}
/**
* 拼音分词.
*
* @param string $text
* @param string|null $wordSplit
*
* @return array
*/
public function split($text, $wordSplit = ' ')
{
if (null === $wordSplit)
{
return swoole_split_pinyin_array($text);
}
else
{
return swoole_split_pinyin_string($text, $wordSplit);
}
}
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
abstract class Base implements BaseInterface
{
/**
* 繁体转简体.
*
* @param string $string
*
* @return array
*/
public function toSimplified($string)
{
return $this->parseResult($this->getResult($string, 'sc'));
}
/**
* 简体转繁体.
*
* @param string $string
*
* @return array
*/
public function toTraditional($string)
{
return $this->parseResult($this->getResult($string, 'tc'));
}
/**
* 处理结果.
*
* @param array $list
*
* @return void
*/
protected function parseResult($list)
{
$strings = [''];
foreach ($list as $pinyins)
{
$count = \count($pinyins);
$oldResultCount = \count($strings);
$oldResult = $strings;
for ($i = 0; $i < $count - 1; ++$i)
{
$strings = array_merge($strings, $oldResult);
}
foreach ($pinyins as $index => $pinyin)
{
for ($i = 0; $i < $oldResultCount; ++$i)
{
$j = $index * $oldResultCount + $i;
$strings[$j] .= $pinyin;
}
}
}
return $strings;
}
/**
* 把字符串转为数组结果.
*
* @param string $string
*
* @return array
*/
abstract protected function getResult($string, $key);
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
interface BaseInterface
{
/**
* 繁体转简体.
*
* @param string $string
*
* @return array
*/
public function toSimplified($string);
/**
* 简体转繁体.
*
* @param string $string
*
* @return array
*/
public function toTraditional($string);
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
use Yurun\Util\Chinese\FFIDriver;
class FFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('FFI');
}
/**
* 繁体转简体.
*
* @param string $string
*
* @return array
*/
public function toSimplified($string)
{
return convert_to_simplified($string);
}
/**
* 简体转繁体.
*
* @param string $string
*
* @return array
*/
public function toTraditional($string)
{
return convert_to_traditional($string);
}
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
use Yurun\Util\Chinese;
class JSON extends Base
{
use \Yurun\Util\Chinese\Traits\JSONInit;
public function __construct()
{
$this->loadChars();
}
/**
* 把字符串转为数组结果.
*
* @param string $string
*
* @return array
*/
protected function getResult($string, $key)
{
$len = mb_strlen($string, 'UTF-8');
$list = [];
$index = \constant('\Yurun\Util\Chinese\JSONIndex::INDEX_' . strtoupper($key));
for ($i = 0; $i < $len; ++$i)
{
$word = mb_substr($string, $i, 1, 'UTF-8');
if (isset(Chinese::$chineseData['chars'][$word][$index]) && '' !== Chinese::$chineseData['chars'][$word][$index])
{
$list[] = explode(',', Chinese::$chineseData['chars'][$word][$index]);
}
else
{
$list[] = [
$word,
];
}
}
return $list;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
use Yurun\Util\Chinese;
class Memory extends Base
{
use \Yurun\Util\Chinese\Traits\MemoryInit;
public function __construct()
{
$this->initData();
}
/**
* 把字符串转为数组结果.
*
* @param string $string
*
* @return array
*/
protected function getResult($string, $key)
{
$len = mb_strlen($string, 'UTF-8');
$list = [];
for ($i = 0; $i < $len; ++$i)
{
$word = mb_substr($string, $i, 1, 'UTF-8');
if (isset(Chinese::$chineseData['chars'][$word][$key]) && [] !== Chinese::$chineseData['chars'][$word][$key])
{
$list[] = Chinese::$chineseData['chars'][$word][$key];
}
else
{
$list[] = [
$word,
];
}
}
return $list;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
use Yurun\Util\Chinese\SQLiteData;
class SQLite extends Base
{
public function __construct()
{
SQLiteData::init();
}
/**
* 把字符串转为数组结果.
*
* @param string $string
*
* @return array
*/
protected function getResult($string, $key)
{
$len = mb_strlen($string, 'UTF-8');
$list = [];
for ($i = 0; $i < $len; ++$i)
{
$word = mb_substr($string, $i, 1, 'UTF-8');
$data = SQLiteData::getData($word, $key);
if (isset($data[$key][0]))
{
$list[] = $data[$key];
}
else
{
$list[] = [
$word,
];
}
}
return $list;
}
}
<?php
namespace Yurun\Util\Chinese\Driver\SimplifiedTraditional;
use Yurun\Util\Chinese\FFIDriver;
class SwooleFFI implements BaseInterface
{
public function __construct()
{
FFIDriver::getHandler('SwooleFFI');
}
/**
* 繁体转简体.
*
* @param string $string
*
* @return array
*/
public function toSimplified($string)
{
return swoole_convert_to_simplified($string);
}
/**
* 简体转繁体.
*
* @param string $string
*
* @return array
*/
public function toTraditional($string)
{
return swoole_convert_to_traditional($string);
}
}
<?php
namespace Yurun\Util\Chinese;
use FFI as PHPFFI;
class FFIDriver
{
/**
* 处理器集合.
*
* @var static[]
*/
private static $handlers;
/**
* .so 文件路径.
*
* @var string|null
*/
public static $library;
/**
* 字符数据文件路径.
*
* @var string|null
*/
public static $characterDataPath;
/**
* 拼音数据文件路径.
*
* @var string|null
*/
public static $pinyinDataPath;
/**
* FFI 对象
*
* @var \FFI
*/
public $ffi;
public function __construct($library = null, $characterDataPath = null, $pinyinDataPath = null)
{
if (!\extension_loaded('FFI'))
{
throw new \RuntimeException('If you want to use FFI mode, you must use PHP>=7.4 and enable FFI extension');
}
$clibPath = \dirname(__DIR__, 2) . '/clib';
if (null === $library)
{
$swooleInstalled = \defined('SWOOLE_VERSION');
$phpVersion = \PHP_MAJOR_VERSION . '.' . \PHP_MINOR_VERSION;
switch (\PHP_OS_FAMILY)
{
case 'Darwin':
if ($swooleInstalled)
{
$library = "libchinese_util-php{$phpVersion}-swoole4.5.dylib";
}
else
{
$library = "libchinese_util-php{$phpVersion}.dylib";
}
break;
case 'Windows':
$library = "chinese_util-php{$phpVersion}-x" . (4 === \PHP_INT_SIZE ? '86' : '64') . '.dll';
break;
default:
if ($swooleInstalled)
{
$library = "libchinese_util-php{$phpVersion}-swoole4.5.so";
}
else
{
$library = "libchinese_util-php{$phpVersion}.so";
}
}
$library = $clibPath . '/' . $library;
}
$this->ffi = $ffi = PHPFFI::cdef(file_get_contents($clibPath . '/include.h'), $library);
$ffi->init_chinese_util();
$dataPath = \dirname(__DIR__, 2) . '/data';
if (!$characterDataPath)
{
$characterDataPath = $dataPath . '/charsData.json';
}
if (!$pinyinDataPath)
{
$pinyinDataPath = $dataPath . '/pinyinData.json';
}
init_chinese_dict($characterDataPath, $pinyinDataPath);
}
/**
* 获取拼音处理器.
*
* @return static
*/
public static function getHandler(string $type)
{
if (!isset(static::$handlers[$type]))
{
static::$handlers[$type] = new static(static::$library, static::$characterDataPath, static::$pinyinDataPath);
}
return static::$handlers[$type];
}
}
<?php
namespace Yurun\Util\Chinese;
class JSONIndex
{
/**
* 数据索引-拼音.
*/
const INDEX_PINYIN = 0;
/**
* 数据索引-对应的简体字.
*/
const INDEX_SC = 1;
/**
* 数据索引-对应的繁体字.
*/
const INDEX_TC = 2;
/**
* 数据索引-是否为简体字.
*/
const INDEX_IS_SC = 3;
/**
* 数据索引-是否为繁体字.
*/
const INDEX_IS_TC = 4;
}
<?php
namespace Yurun\Util\Chinese;
use Yurun\Util\Chinese;
abstract class Money
{
/**
* 处理器.
*
* @var \Yurun\Util\Chinese\Driver\Money\BaseInterface
*/
public static $handler;
/**
* 处理器的模式.
*
* @var string
*/
private static $handlerMode = 'Memory';
/**
* 中文金额大写转数字.
*
* @param string $text
*
* @return string
*/
public static function toNumber($text)
{
return static::getHandler()->toNumber($text);
}
/**
* 数字转为中文金额大写.
*
* @param string $number
* @param array $options
*
* @return string
*/
public static function toChinese($number, $options = [])
{
return static::getHandler()->toChinese($number, $options);
}
/**
* 获取处理器.
*
* @return \Yurun\Util\Chinese\Driver\Money\BaseInterface
*/
protected static function getHandler()
{
$mode = Chinese::getMode();
if (null === static::$handler || $mode !== static::$handlerMode)
{
if (null === $mode)
{
$mode = static::$handlerMode;
}
else
{
static::$handlerMode = $mode;
}
$className = '\Yurun\Util\Chinese\Driver\Money\\' . $mode;
static::$handler = new $className();
}
return static::$handler;
}
}
<?php
namespace Yurun\Util\Chinese;
use Yurun\Util\Chinese;
abstract class Number
{
/**
* 处理器.
*
* @var \Yurun\Util\Chinese\Driver\Number\BaseInterface
*/
public static $handler;
/**
* 处理器的模式.
*
* @var string
*/
private static $handlerMode = 'Memory';
/**
* 中文口语化数字转数字.
*
* @param string $text
*
* @return string
*/
public static function toNumber($text)
{
return static::getHandler()->toNumber($text);
}
/**
* 数字转为中文口语化数字.
*
* @param string $number
* @param array $options
*
* @return string
*/
public static function toChinese($number, $options = [])
{
return static::getHandler()->toChinese($number, $options);
}
/**
* 获取处理器.
*
* @return \Yurun\Util\Chinese\Driver\Number\BaseInterface
*/
protected static function getHandler()
{
$mode = Chinese::getMode();
if (null === static::$handler || $mode !== static::$handlerMode)
{
if (null === $mode)
{
$mode = static::$handlerMode;
}
else
{
static::$handlerMode = $mode;
}
$className = '\Yurun\Util\Chinese\Driver\Number\\' . $mode;
static::$handler = new $className();
}
return static::$handler;
}
}
<?php
namespace Yurun\Util\Chinese;
use Yurun\Util\Chinese;
class Pinyin
{
/**
* 转换为全拼
*/
const CONVERT_MODE_PINYIN = 1;
/**
* 转换为带声调读音的拼音.
*/
const CONVERT_MODE_PINYIN_SOUND = 2;
/**
* 转换为带声调读音的拼音,但声调表示为数字.
*/
const CONVERT_MODE_PINYIN_SOUND_NUMBER = 4;
/**
* 转换为拼音首字母.
*/
const CONVERT_MODE_PINYIN_FIRST = 8;
/**
* 转换为上面支持的所有类型.
*/
const CONVERT_MODE_FULL = 15;
/**
* 拼音处理器.
*
* @var \Yurun\Util\Chinese\Driver\Pinyin\BaseInterface
*/
public static $handler;
/**
* 处理器的模式.
*
* @var string
*/
private static $handlerMode = 'JSON';
/**
* 把字符串转为拼音结果,返回的数组成员为数组.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
*
* @return array
*/
public static function convert($string, $mode = self::CONVERT_MODE_FULL)
{
return static::getHandler()->convert($string, $mode);
}
/**
* 把字符串转为拼音结果,返回的数组成员为字符串.
*
* @param string $string
* @param int $mode
* @param string $wordSplit
* @param bool $splitNotPinyinChar 分割无拼音字符。如果为true,如123结果分割为['1','2','3'];如果为false,如123结果分割为['123']
*
* @return array
*/
public static function toText($string, $mode = self::CONVERT_MODE_FULL, $wordSplit = ' ', $splitNotPinyinChar = true)
{
return static::getHandler()->convert($string, $mode, $wordSplit, $splitNotPinyinChar);
}
/**
* 获取拼音处理器.
*
* @return \Yurun\Util\Chinese\Driver\Pinyin\BaseInterface
*/
protected static function getHandler()
{
$mode = Chinese::getMode();
if (null === static::$handler || $mode !== static::$handlerMode)
{
if (null === $mode)
{
$mode = static::$handlerMode;
}
else
{
static::$handlerMode = $mode;
}
$className = '\Yurun\Util\Chinese\Driver\Pinyin\\' . $mode;
static::$handler = new $className();
}
return static::$handler;
}
}
<?php
namespace Yurun\Util\Chinese;
use Yurun\Util\Chinese;
class PinyinSplit
{
/**
* 拼音分词处理器.
*
* @var \Yurun\Util\Chinese\Driver\PinyinSplit\BaseInterface
*/
public static $handler;
/**
* 处理器的模式.
*
* @var string
*/
private static $handlerMode = 'Memory';
/**
* 拼音分词.
*
* @param string $text
* @param string|null $wordSplit
*
* @return array
*/
public static function split($text, $wordSplit = ' ')
{
return static::getHandler()->split($text, $wordSplit);
}
/**
* 获取拼音处理器.
*
* @return \Yurun\Util\Chinese\Driver\PinyinSplit\BaseInterface
*/
protected static function getHandler()
{
$mode = Chinese::getMode();
if (null === static::$handler || $mode !== static::$handlerMode)
{
if (null === $mode)
{
$mode = static::$handlerMode;
}
else
{
static::$handlerMode = $mode;
}
if (\in_array($mode, [
'JSON',
'Memory',
'SQLite',
]))
{
$className = '\Yurun\Util\Chinese\Driver\PinyinSplit\Memory';
}
else
{
$className = '\Yurun\Util\Chinese\Driver\PinyinSplit\\' . $mode;
}
static::$handler = new $className();
}
return static::$handler;
}
}
<?php
namespace Yurun\Util\Chinese;
use Yurun\Util\Chinese;
class SQLiteData
{
public static $pdo;
public static function init()
{
if (null === static::$pdo)
{
if (isset(Chinese::$option['sqliteDbPath']))
{
$path = Chinese::$option['sqliteDbPath'];
}
else
{
$path = \dirname(\dirname(__DIR__)) . '/data/chineseData.sqlite';
}
static::$pdo = new \PDO('sqlite:' . $path, '', '');
}
}
public static function getAllData()
{
$stmt = static::$pdo->query('select * from chars');
if (false === $stmt)
{
throw new \Exception(implode(' ', static::$pdo->errorInfo()));
}
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$s = \count($data);
for ($i = 0; $i < $s; ++$i)
{
static::parseResultData($data[$i]);
}
return $data;
}
public static function getData($char, $fields = '*')
{
$stmt = static::$pdo->prepare('select ' . $fields . ' from chars where char = :char limit 1');
if (false === $stmt)
{
throw new \Exception(implode(' ', static::$pdo->errorInfo()));
}
$stmt->bindValue('char', $char);
$result = $stmt->execute();
if (false === $result)
{
throw new \Exception(implode(' ', $stmt->errorInfo()));
}
$data = $stmt->fetch(\PDO::FETCH_ASSOC);
static::parseResultData($data);
return $data;
}
private static function parseResultData(&$data)
{
if (isset($data['pinyin']))
{
$data['pinyin'] = isset($data['pinyin'][0]) ? explode(',', $data['pinyin']) : [];
}
if (isset($data['pinyinSound']))
{
$data['pinyinSound'] = isset($data['pinyinSound'][0]) ? explode(',', $data['pinyinSound']) : [];
}
if (isset($data['pinyinSoundNumber']))
{
$data['pinyinSoundNumber'] = isset($data['pinyinSoundNumber'][0]) ? explode(',', $data['pinyinSoundNumber']) : [];
}
if (isset($data['sc']))
{
$data['sc'] = isset($data['sc'][0]) ? explode(',', $data['sc']) : [];
}
if (isset($data['tc']))
{
$data['tc'] = isset($data['tc'][0]) ? explode(',', $data['tc']) : [];
}
if (isset($data['isSC']))
{
$data['isSC'] = 1 == $data['isSC'];
}
if (isset($data['isTC']))
{
$data['isTC'] = 1 == $data['isTC'];
}
}
}
<?php
namespace Yurun\Util\Chinese;
use Yurun\Util\Chinese;
class SimplifiedAndTraditional
{
/**
* 处理器.
*
* @var \Yurun\Util\Chinese\Driver\SimplifiedTraditional\BaseInterface
*/
public static $handler;
/**
* 处理器的模式.
*
* @var string
*/
private static $handlerMode = 'Memory';
/**
* 繁体转简体.
*
* @param string $string
*
* @return array
*/
public static function toSimplified($string)
{
return static::getHandler()->toSimplified($string);
}
/**
* 简体转繁体.
*
* @param string $string
*
* @return array
*/
public static function toTraditional($string)
{
return static::getHandler()->toTraditional($string);
}
/**
* 获取处理器.
*
* @return \Yurun\Util\Chinese\Driver\SimplifiedTraditional\BaseInterface
*/
protected static function getHandler()
{
$mode = Chinese::getMode();
if (null === static::$handler || $mode !== static::$handlerMode)
{
if (null === $mode)
{
$mode = static::$handlerMode;
}
else
{
static::$handlerMode = $mode;
}
$className = '\Yurun\Util\Chinese\Driver\SimplifiedTraditional\\' . $mode;
static::$handler = new $className();
}
return static::$handler;
}
}
<?php
namespace Yurun\Util\Chinese\Traits;
use Yurun\Util\Chinese;
trait JSONInit
{
protected function loadChars()
{
if (!isset(Chinese::$chineseData['chars']))
{
if (!empty(Chinese::$option['charsData']))
{
Chinese::$chineseData['chars'] = Chinese::$option['charsData'];
}
elseif (empty(Chinese::$option['charsDataPath']))
{
Chinese::$chineseData['chars'] = json_decode(file_get_contents(\dirname(\dirname(\dirname(__DIR__))) . '/data/charsData.json'), true);
}
else
{
Chinese::$chineseData['chars'] = json_decode(file_get_contents(Chinese::$option['charsDataPath']), true);
}
}
}
protected function loadPinyinSound()
{
if (!isset(Chinese::$chineseData['pinyinSound']))
{
if (!empty(Chinese::$option['pinyinSoundData']))
{
Chinese::$chineseData['pinyinSound'] = Chinese::$option['pinyinSoundData'];
}
elseif (empty(Chinese::$option['pinyinSoundDataPath']))
{
Chinese::$chineseData['pinyinSound'] = json_decode(file_get_contents(\dirname(\dirname(\dirname(__DIR__))) . '/data/pinyinData.json'), true)['sound'];
}
else
{
Chinese::$chineseData['pinyinSound'] = json_decode(file_get_contents(Chinese::$option['pinyinSoundDataPath']), true)['sound'];
}
}
}
}
<?php
namespace Yurun\Util\Chinese\Traits;
use Yurun\Util\Chinese;
use Yurun\Util\Chinese\SQLiteData;
trait MemoryInit
{
protected function initData()
{
SQLiteData::init();
if (!isset(Chinese::$chineseData['chars']))
{
$data = SQLiteData::getAllData();
$this->parseData($data);
Chinese::$chineseData['chars'] = $data;
}
}
/**
* 处理数据.
*
* @param array $array
*/
protected function parseData(&$array)
{
$s = \count($array);
for ($i = 0; $i < $s; ++$i)
{
$char = $array[$i]['char'];
unset($array[$i]['char']);
$array[$char] = $array[$i];
unset($array[$i]);
}
}
}
<?php
namespace Yurun\Util\Chinese;
abstract class Util
{
public static function mbLtrim($string, $trim_chars = '\s')
{
return preg_replace('/^[' . $trim_chars . ']*(.*?)$/u', '\\1', $string);
}
public static function mbRtrim($string, $trim_chars = '\s')
{
return preg_replace('/^(.*?)[' . $trim_chars . ']*$/u', '\\1', $string);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment