VicDict.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: tanszhe
  5. * Date: 2017/12/21
  6. * Time: 下午8:16
  7. */
  8. namespace addons\cms\library;
  9. class VicDict
  10. {
  11. private $word = [];
  12. /**
  13. * 词典地址
  14. * @var string
  15. */
  16. private $code = 'utf-8';
  17. private $end = ['\\' => 1];
  18. private $default_end = ['\\' => 1];
  19. private $end_key = '\\';
  20. private $type = 'igb';
  21. public function __construct($type = 'igb')
  22. {
  23. $this->type = $type;
  24. if (file_exists(_VIC_WORD_DICT_PATH_)) {
  25. if ($type == 'igb') {
  26. $this->word = igbinary_unserialize(file_get_contents(_VIC_WORD_DICT_PATH_));
  27. } else {
  28. $this->word = json_decode(file_get_contents(_VIC_WORD_DICT_PATH_), true);
  29. }
  30. }
  31. }
  32. /**
  33. * @param string $word
  34. * @param null|string $x 词性
  35. * @return bool
  36. */
  37. public function add($word, $x = null)
  38. {
  39. $this->end = ['\\x' => $x] + $this->default_end;
  40. $word = $this->filter($word);
  41. if ($word) {
  42. return $this->merge($word);
  43. }
  44. return false;
  45. }
  46. private function merge($word)
  47. {
  48. $ar = $this->toArr($word);
  49. $br = $ar;
  50. $wr = &$this->word;
  51. foreach ($ar as $i => $v) {
  52. array_shift($br);
  53. if (!isset($wr[$v])) {
  54. $wr[$v] = $this->dict($br, $this->end);
  55. return true;
  56. } else {
  57. $wr = &$wr[$v];
  58. }
  59. }
  60. if (!isset($wr[$this->end_key])) {
  61. foreach ($this->end as $k => $v) {
  62. $wr[$k] = $v;
  63. $wr[$k] = $v;
  64. }
  65. }
  66. return true;
  67. }
  68. public function save()
  69. {
  70. if ($this->type == 'igb') {
  71. $str = igbinary_serialize($this->word);
  72. } else {
  73. $str = json_encode($this->word);
  74. }
  75. return file_put_contents(_VIC_WORD_DICT_PATH_, $str);
  76. }
  77. private function filter($word)
  78. {
  79. return str_replace(["\n", "\t"], '', trim($word));
  80. }
  81. private function dict($arr, $v, $i = 0)
  82. {
  83. if (isset($arr[$i])) {
  84. return [$arr[$i] => $this->dict($arr, $v, $i + 1)];
  85. } else {
  86. return $v;
  87. }
  88. }
  89. private function toArr($str)
  90. {
  91. $l = mb_strlen($str, $this->code);
  92. $r = [];
  93. for ($i = 0; $i < $l; $i++) {
  94. $r[] = mb_substr($str, $i, 1, $this->code);
  95. }
  96. return $r;
  97. }
  98. }