Compare commits

...

203 Commits

Author SHA1 Message Date
as2252258 ca274a3910 Revert "改名"
This reverts commit fdf58326
2022-02-10 11:37:54 +08:00
as2252258 4d6f7d1d13 Revert "改名"
This reverts commit fdf58326
2022-02-03 14:54:38 +08:00
as2252258 8296cda1f2 Revert "改名"
This reverts commit fdf58326
2022-01-25 15:50:17 +08:00
as2252258 3bb14c5acb Revert "改名"
This reverts commit fdf58326
2022-01-25 15:49:48 +08:00
as2252258 b5bfff66dd 1 2022-01-25 02:00:42 +08:00
as2252258 adb2269df0 Revert "改名"
This reverts commit fdf58326
2022-01-20 19:05:57 +08:00
as2252258 b557f15a98 Revert "改名"
This reverts commit fdf58326
2022-01-20 19:04:16 +08:00
as2252258 862acf1db1 Revert "改名"
This reverts commit fdf58326
2022-01-18 16:01:02 +08:00
as2252258 a2272edc76 Revert "改名"
This reverts commit fdf58326
2022-01-18 10:29:32 +08:00
as2252258 555d653288 Revert "改名"
This reverts commit fdf58326
2022-01-18 10:18:13 +08:00
as2252258 45cf88e52c Revert "改名"
This reverts commit fdf58326
2022-01-17 19:04:26 +08:00
as2252258 a8f840bfb2 Revert "改名"
This reverts commit fdf58326
2022-01-17 18:48:57 +08:00
as2252258 d8222366b1 Revert "改名"
This reverts commit fdf58326
2022-01-17 18:45:00 +08:00
as2252258 fbe13eaa7e Revert "改名"
This reverts commit fdf58326
2022-01-17 14:04:37 +08:00
as2252258 466df3387f Revert "改名"
This reverts commit fdf58326
2022-01-17 10:59:55 +08:00
as2252258 fa76b5170a Revert "改名"
This reverts commit fdf58326
2022-01-15 10:23:57 +08:00
as2252258 b0c66c9c6a Revert "改名"
This reverts commit fdf58326
2022-01-14 16:50:01 +08:00
as2252258 2ffdf83645 Revert "改名"
This reverts commit fdf58326
2022-01-14 16:05:12 +08:00
as2252258 c3a3551ba3 Revert "改名"
This reverts commit fdf58326
2022-01-14 15:52:38 +08:00
as2252258 829c063700 Revert "改名"
This reverts commit fdf58326
2022-01-14 14:54:13 +08:00
as2252258 eaf251ac53 Revert "改名"
This reverts commit fdf58326
2022-01-14 14:45:03 +08:00
as2252258 776cc80495 Revert "改名"
This reverts commit fdf58326
2022-01-14 14:43:04 +08:00
as2252258 103cc96103 Revert "改名"
This reverts commit fdf58326
2022-01-14 14:19:52 +08:00
as2252258 f2da99efce Revert "改名"
This reverts commit fdf58326
2022-01-14 14:18:29 +08:00
as2252258 49d0ba7b3c Revert "改名"
This reverts commit fdf58326
2022-01-14 11:43:02 +08:00
as2252258 a6ed92206e Revert "改名"
This reverts commit fdf58326
2022-01-14 11:41:30 +08:00
as2252258 bb9b9dbcd2 Revert "改名"
This reverts commit fdf58326
2022-01-14 11:40:20 +08:00
as2252258 9782147a47 Revert "改名"
This reverts commit fdf58326
2022-01-14 11:39:52 +08:00
as2252258 7598bdbd63 Revert "改名"
This reverts commit fdf58326
2022-01-14 11:38:28 +08:00
as2252258 a569bd6897 Revert "改名"
This reverts commit fdf58326
2022-01-14 11:29:16 +08:00
as2252258 ffeef3ff4b Revert "改名"
This reverts commit fdf58326
2022-01-13 18:48:13 +08:00
as2252258 7f6a0c01e0 Revert "改名"
This reverts commit fdf58326
2022-01-13 18:41:16 +08:00
as2252258 32f9ebc2a2 Revert "改名"
This reverts commit fdf58326
2022-01-13 18:39:39 +08:00
as2252258 f35ffe6ff1 Revert "改名"
This reverts commit fdf58326
2022-01-13 18:33:04 +08:00
as2252258 9a76ee0184 Revert "改名"
This reverts commit fdf58326
2022-01-13 10:15:04 +08:00
as2252258 249f9b1c6f Revert "改名"
This reverts commit fdf58326
2022-01-12 18:52:13 +08:00
as2252258 1df2d43b8b Revert "改名"
This reverts commit fdf58326
2022-01-12 18:50:48 +08:00
as2252258 2daac841a3 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:49:57 +08:00
as2252258 28cd946219 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:30:28 +08:00
as2252258 70015f7ab8 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:29:49 +08:00
as2252258 a467056c86 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:28:51 +08:00
as2252258 a2a3f0fc40 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:27:49 +08:00
as2252258 cfbebeb951 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:26:54 +08:00
as2252258 94851c3f51 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:22:53 +08:00
as2252258 1896dc90b4 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:14:15 +08:00
as2252258 6168adb401 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:12:56 +08:00
as2252258 5e742e7196 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:09:49 +08:00
as2252258 4605fc9162 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:08:28 +08:00
as2252258 54f19fb058 Revert "改名"
This reverts commit fdf58326
2022-01-12 18:05:49 +08:00
as2252258 a9165b601a Revert "改名"
This reverts commit fdf58326
2022-01-12 18:03:09 +08:00
as2252258 5b35c4de4a Revert "改名"
This reverts commit fdf58326
2022-01-12 18:02:45 +08:00
as2252258 8b6aff5c7b Revert "改名"
This reverts commit fdf58326
2022-01-12 18:01:55 +08:00
as2252258 1d3b45e2c3 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:58:01 +08:00
as2252258 f2ad97c7f0 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:55:25 +08:00
as2252258 19b3f0f1e9 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:54:18 +08:00
as2252258 ebd643772d Revert "改名"
This reverts commit fdf58326
2022-01-12 17:53:27 +08:00
as2252258 08d9551245 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:52:18 +08:00
as2252258 59eec80939 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:46:16 +08:00
as2252258 241385b575 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:39:11 +08:00
as2252258 73ce2b8a50 Revert "改名"
This reverts commit fdf58326
2022-01-12 17:38:25 +08:00
as2252258 6f80b2fe6a Revert "改名"
This reverts commit fdf58326
2022-01-12 17:17:47 +08:00
as2252258 8955891c2f Revert "改名"
This reverts commit fdf58326
2022-01-12 16:01:55 +08:00
as2252258 035138a779 Revert "改名"
This reverts commit fdf58326
2022-01-12 16:00:11 +08:00
as2252258 c6e6c8d68d Revert "改名"
This reverts commit fdf58326
2022-01-12 15:47:28 +08:00
as2252258 6a30fdfa8d Revert "改名"
This reverts commit fdf58326
2022-01-12 15:08:22 +08:00
as2252258 367e1cd122 Revert "改名"
This reverts commit fdf58326
2022-01-12 15:07:40 +08:00
as2252258 667d311d73 Revert "改名"
This reverts commit fdf58326
2022-01-12 14:52:01 +08:00
as2252258 375f396467 Revert "改名"
This reverts commit fdf58326
2022-01-12 14:43:28 +08:00
as2252258 7b1cc1bd7b Revert "改名"
This reverts commit fdf58326
2022-01-12 14:10:33 +08:00
as2252258 1ae1d78ddf Revert "改名"
This reverts commit fdf58326
2022-01-12 11:52:59 +08:00
as2252258 00212d133d Revert "改名"
This reverts commit fdf58326
2022-01-12 11:39:17 +08:00
as2252258 7fbe9fbf44 Revert "改名"
This reverts commit fdf58326
2022-01-12 11:20:34 +08:00
as2252258 de1aff9efd Revert "改名"
This reverts commit fdf58326
2022-01-11 16:17:25 +08:00
as2252258 cef09a11ef Revert "改名"
This reverts commit fdf58326
2022-01-11 16:16:05 +08:00
as2252258 7122018a2a Revert "改名"
This reverts commit fdf58326
2022-01-11 15:53:31 +08:00
as2252258 f8763953c5 Revert "改名"
This reverts commit fdf58326
2022-01-11 15:48:12 +08:00
as2252258 22560d77d6 Revert "改名"
This reverts commit fdf58326
2022-01-10 11:39:56 +08:00
as2252258 483c898f51 1 2022-01-10 02:13:11 +08:00
as2252258 1fa651c587 1 2022-01-10 02:10:37 +08:00
as2252258 f7ca56a9b0 1 2022-01-09 17:56:47 +08:00
as2252258 4fa5c23c10 1 2022-01-09 16:07:58 +08:00
as2252258 f46af653f2 1 2022-01-09 14:33:33 +08:00
as2252258 5e02a79bf0 e 2022-01-09 03:50:38 +08:00
as2252258 08dc3e262b 1 2022-01-09 03:46:42 +08:00
as2252258 8c5e52940f 1 2022-01-09 02:44:09 +08:00
as2252258 4dbcacdd1f Revert "改名"
This reverts commit fdf58326
2022-01-08 19:11:23 +08:00
as2252258 97cd1a0ebf Revert "改名"
This reverts commit fdf58326
2022-01-08 18:49:08 +08:00
as2252258 7165a67294 Revert "改名"
This reverts commit fdf58326
2022-01-08 18:10:52 +08:00
as2252258 4bc7451424 Revert "改名"
This reverts commit fdf58326
2022-01-08 18:10:41 +08:00
as2252258 d7d0f685dc Revert "改名"
This reverts commit fdf58326
2022-01-08 10:07:19 +08:00
as2252258 8ee7d30d6a Revert "改名"
This reverts commit fdf58326
2022-01-07 19:01:00 +08:00
as2252258 224009e7e6 Revert "改名"
This reverts commit fdf58326
2022-01-07 19:00:45 +08:00
as2252258 b4551ae2fd Revert "改名"
This reverts commit fdf58326
2022-01-07 18:16:30 +08:00
as2252258 5ca94925e3 Revert "改名"
This reverts commit fdf58326
2022-01-07 18:05:17 +08:00
as2252258 0afa8fc400 Revert "改名"
This reverts commit fdf58326
2022-01-07 17:59:37 +08:00
as2252258 842220e4de Revert "改名"
This reverts commit fdf58326
2022-01-07 17:57:27 +08:00
as2252258 c9726e5778 Revert "改名"
This reverts commit fdf58326
2022-01-07 14:38:36 +08:00
as2252258 f867f4be9e Revert "改名"
This reverts commit fdf58326
2022-01-06 19:05:15 +08:00
as2252258 45319c3733 Revert "改名"
This reverts commit fdf58326
2022-01-04 17:27:37 +08:00
as2252258 06c9459f14 Revert "改名"
This reverts commit fdf58326
2022-01-04 16:25:03 +08:00
as2252258 5fd2abcb69 Revert "改名"
This reverts commit fdf58326
2022-01-04 16:22:37 +08:00
as2252258 58a3d91df3 Merge remote-tracking branch 'origin/master' 2022-01-04 16:05:08 +08:00
as2252258 c61842402a Revert "改名"
This reverts commit fdf58326
2022-01-04 16:04:22 +08:00
as2252258 623bae9e97 1 2022-01-04 00:07:26 +08:00
as2252258 12610c218c 1 2022-01-04 00:07:14 +08:00
as2252258 c3ca24884e Revert "改名"
This reverts commit fdf58326
2021-12-31 16:47:17 +08:00
as2252258 02c14874a2 Revert "改名"
This reverts commit fdf58326
2021-12-31 16:46:13 +08:00
as2252258 6eff48e22f Revert "改名"
This reverts commit fdf58326
2021-12-30 18:10:51 +08:00
as2252258 6c46a54d4b Revert "改名"
This reverts commit fdf58326
2021-12-28 17:54:51 +08:00
as2252258 03287cfd65 Revert "改名"
This reverts commit fdf58326
2021-12-28 14:16:45 +08:00
as2252258 93ce4c16b6 Revert "改名"
This reverts commit fdf58326
2021-12-27 15:24:29 +08:00
as2252258 4b92edd40f 1 2021-12-24 01:19:43 +08:00
as2252258 a76c81df8e 改名 2021-12-23 18:36:14 +08:00
as2252258 aa59caad07 改名 2021-12-23 18:22:27 +08:00
as2252258 6fd8a5dd34 1 2021-12-22 03:29:27 +08:00
as2252258 9ca53a73ce 1 2021-12-22 03:29:14 +08:00
as2252258 d904e78864 1 2021-12-18 03:27:14 +08:00
as2252258 0d64ef7ac4 1 2021-12-17 04:57:46 +08:00
as2252258 154d9d74d6 1 2021-12-17 04:43:20 +08:00
as2252258 2c61abff01 1 2021-12-17 04:41:00 +08:00
as2252258 b4ce762cf3 1 2021-12-17 04:26:54 +08:00
as2252258 4b3c2234af 1 2021-12-17 04:24:40 +08:00
as2252258 7ee78a9642 1 2021-12-17 04:24:01 +08:00
as2252258 f9838f781d 1 2021-12-17 04:23:12 +08:00
as2252258 848416af4f 1 2021-12-17 04:22:13 +08:00
as2252258 0216e761be 1 2021-12-17 04:17:53 +08:00
as2252258 acf6631c5c 1 2021-12-17 04:15:59 +08:00
as2252258 64e4307a57 1 2021-12-12 06:37:52 +08:00
as2252258 ab672127e6 1 2021-12-12 02:46:30 +08:00
as2252258 6e5b545a1e 1 2021-12-12 02:45:39 +08:00
as2252258 8229395e6d 1 2021-12-12 02:41:31 +08:00
as2252258 d5d2b04321 1 2021-12-11 17:56:35 +08:00
as2252258 ce9c184c83 1 2021-12-11 17:40:16 +08:00
as2252258 620de34559 1 2021-12-11 17:38:53 +08:00
as2252258 b01c71ea5e 1 2021-12-11 17:38:15 +08:00
as2252258 90e1f7eb29 1 2021-12-11 17:35:44 +08:00
as2252258 f3ad09ef66 1 2021-12-11 17:34:05 +08:00
as2252258 dfccb8816c 1 2021-12-11 17:32:28 +08:00
as2252258 1670ff3fef 1 2021-12-11 05:33:46 +08:00
as2252258 8870a7ca27 1 2021-12-11 05:33:00 +08:00
as2252258 ebb7ac9673 改名 2021-12-09 17:01:18 +08:00
as2252258 5aad8d2001 改名 2021-12-08 11:45:19 +08:00
as2252258 80713788c9 改名 2021-12-08 11:39:57 +08:00
as2252258 9f36acbbca 改名 2021-12-08 11:32:32 +08:00
as2252258 044d213a69 改名 2021-12-07 16:44:12 +08:00
as2252258 e5fe525f82 改名 2021-12-07 16:02:07 +08:00
as2252258 39e4e52908 改名 2021-12-07 16:00:52 +08:00
as2252258 f62014ff34 改名 2021-12-07 15:59:13 +08:00
as2252258 7935e6a6a3 改名 2021-12-07 15:53:56 +08:00
as2252258 d2acd50352 改名 2021-12-06 18:07:33 +08:00
as2252258 d02337ec22 改名 2021-12-06 17:58:11 +08:00
as2252258 57f12b6701 改名 2021-12-06 17:22:26 +08:00
as2252258 d500fd21ce 改名 2021-12-06 16:14:48 +08:00
as2252258 30d7b8684e 改名 2021-12-06 16:13:52 +08:00
as2252258 d8eb4d4e45 改名 2021-12-06 16:03:39 +08:00
as2252258 7004c5c0f8 改名 2021-12-06 15:54:31 +08:00
as2252258 81e55ecdf1 改名 2021-12-06 15:52:05 +08:00
as2252258 20adc186d4 改名 2021-12-06 15:51:29 +08:00
as2252258 8c16d9f4b3 改名 2021-12-06 15:48:57 +08:00
as2252258 b3e06a680a 改名 2021-12-06 15:47:12 +08:00
as2252258 3176443e5c 改名 2021-12-06 15:39:35 +08:00
as2252258 83962fa3ba 改名 2021-12-06 14:49:47 +08:00
as2252258 5475f2cd51 改名 2021-12-06 14:45:12 +08:00
as2252258 30212c0b86 改名 2021-12-06 14:44:18 +08:00
as2252258 4731463897 改名 2021-12-06 14:43:46 +08:00
as2252258 87e901f5b1 改名 2021-12-06 14:42:54 +08:00
as2252258 66f87b6da4 改名 2021-12-06 14:41:05 +08:00
as2252258 0007242b70 改名 2021-12-06 14:40:18 +08:00
as2252258 8653e6914b 改名 2021-12-06 14:39:03 +08:00
as2252258 816fec8ef4 改名 2021-12-06 14:38:17 +08:00
as2252258 b0ef09fd35 改名 2021-12-06 14:38:06 +08:00
as2252258 f7a2d6f30e 改名 2021-12-06 14:32:04 +08:00
as2252258 2950ba8fd5 改名 2021-12-06 14:24:41 +08:00
as2252258 2de5c82a73 改名 2021-12-06 14:22:08 +08:00
as2252258 758c4e7d5b 改名 2021-12-06 14:12:03 +08:00
as2252258 33f045aec7 改名 2021-12-06 13:49:01 +08:00
as2252258 35189de442 改名 2021-12-06 11:44:01 +08:00
as2252258 34e7fc0392 改名 2021-12-03 18:40:27 +08:00
as2252258 a3ce9f52ba 改名 2021-12-03 18:22:26 +08:00
as2252258 6e7da1b0ed 改名 2021-12-03 17:40:21 +08:00
as2252258 a6e0b5c1a2 改名 2021-12-03 16:24:44 +08:00
as2252258 13ab14f965 改名 2021-12-03 15:42:05 +08:00
as2252258 6729094f63 改名 2021-12-03 15:35:16 +08:00
as2252258 e1aeb17a5a 改名 2021-12-03 14:46:38 +08:00
as2252258 b9e20051ef 改名 2021-12-02 14:06:57 +08:00
as2252258 4ab6332176 改名 2021-12-01 19:05:10 +08:00
as2252258 abe2dad521 改名 2021-12-01 19:05:00 +08:00
as2252258 b0f70a13da 改名 2021-12-01 15:16:08 +08:00
as2252258 1e8aca91dd 改名 2021-12-01 14:08:09 +08:00
as2252258 b4ac5c4758 改名 2021-11-30 19:04:29 +08:00
as2252258 d161477957 改名 2021-11-30 19:04:16 +08:00
as2252258 a26b99dd1e 改名 2021-11-30 18:33:22 +08:00
as2252258 86e4a92ab0 改名 2021-11-30 18:31:41 +08:00
as2252258 ea425bb82d 改名 2021-11-30 18:30:15 +08:00
as2252258 ad0154d319 改名 2021-11-30 18:29:10 +08:00
as2252258 edb70d2b9b 改名 2021-11-30 18:26:23 +08:00
as2252258 9f3355cab4 改名 2021-11-30 18:23:56 +08:00
as2252258 4107b5bb07 改名 2021-11-30 15:48:18 +08:00
as2252258 048960c572 改名 2021-11-30 15:14:42 +08:00
as2252258 b826e1f594 改名 2021-11-30 15:10:01 +08:00
as2252258 e5b57cbcdb 改名 2021-11-30 14:59:51 +08:00
as2252258 2870a64792 改名 2021-11-30 14:32:56 +08:00
as2252258 4d1587bc8d 改名 2021-11-29 14:35:09 +08:00
123 changed files with 11797 additions and 11596 deletions
+9 -9
View File
@@ -1,9 +1,9 @@
### 該問題是如何引起的? ### 該問題是如何引起的?
### 重現步驟 ### 重現步驟
### 報錯信息 ### 報錯信息
+12 -12
View File
@@ -1,12 +1,12 @@
### 該Pull Request關聯的Issue ### 該Pull Request關聯的Issue
### 修改描述 ### 修改描述
### 測試用例 ### 測試用例
### 修復效果的截屏 ### 修復效果的截屏
+37 -37
View File
@@ -1,37 +1,37 @@
# Created by .ignore support plugin (hsz.mobi) # Created by .ignore support plugin (hsz.mobi)
### Yii template ### Yii template
assets/* assets/*
!assets/.gitignore !assets/.gitignore
protected/runtime/* protected/runtime/*
!protected/runtime/.gitignore !protected/runtime/.gitignore
protected/data/*.db protected/data/*.db
themes/classic/views/ themes/classic/views/
### Example user template template ### Example user template template
### Example user template ### Example user template
# IntelliJ project files # IntelliJ project files
.idea .idea
*.iml *.iml
out out
gen gen
db/ db/
async-queue/ async-queue/
composer.lock composer.lock
*.log *.log
commands/result commands/result
config/setting.php config/setting.php
tests/ tests/
vendor/ vendor/
runtime/ runtime/
*.xml *.xml
*.lock *.lock
oot oot
d d
composer.lock composer.lock
+18 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
namespace PHPSTORM_META { namespace PHPSTORM_META {
// Reflect // Reflect
use Kiri\Di\Container; use Kiri\Di\Container;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
override(ContainerInterface::get(0), map('@')); override(ContainerInterface::get(0), map('@'));
override(Container::get(0), map('@')); override(Container::get(0), map('@'));
override(Container::make(0), map('@')); override(Container::make(0), map('@'));
override(Container::create(0), map('@')); override(Container::create(0), map('@'));
// override(\Hyperf\Utils\Context::get(0), map('@')); // override(\Hyperf\Utils\Context::get(0), map('@'));
// override(\make(0), map('@')); // override(\make(0), map('@'));
override(\di(0), map('@')); override(\di(0), map('@'));
override(\duplicate(0), map('@')); override(\duplicate(0), map('@'));
} }
+18 -287
View File
@@ -2,36 +2,29 @@
declare(strict_types=1); declare(strict_types=1);
namespace Kiri; error_reporting(0);
use Annotation\Annotation;
use Database\Collection; use Database\Collection;
use Database\ModelInterface; use Database\ModelInterface;
use Exception;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Annotation\Annotation;
use Kiri\Application;
use Kiri\Core\Json; use Kiri\Core\Json;
use Kiri\Di\Container; use Kiri\Di\Container;
use Kiri\Environmental;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use ReflectionException;
use Server\ServerManager;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Process; use Swoole\Process;
use Swoole\WebSocket\Server; use Swoole\WebSocket\Server;
defined('DB_ERROR_BUSY') or define('DB_ERROR_BUSY', 'The database is busy. Please try again later.'); defined('DB_ERROR_BUSY') or define('DB_ERROR_BUSY', 'The database is busy. Please try again later.');
defined('SELECT_IS_NULL') or define('SELECT_IS_NULL', 'Query data does not exist, please check the relevant conditions.'); defined('SELECT_IS_NULL') or define('SELECT_IS_NULL', 'Query data does not exist, please check the relevant conditions.');
defined('PARAMS_IS_NULL') or define('PARAMS_IS_NULL', 'Required items cannot be empty, please add.'); defined('PARAMS_IS_NULL') or define('PARAMS_IS_NULL', 'Required items cannot be empty, please add.');
defined('CONTROLLER_PATH') or define('CONTROLLER_PATH', APP_PATH . 'app/Controllers/'); defined('CONTROLLER_PATH') or define('CONTROLLER_PATH', realpath(APP_PATH . 'controllers/'));
defined('CRONTAB_PATH') or define('CRONTAB_PATH', APP_PATH . 'app/Crontab/'); defined('MODEL_PATH') or define('MODEL_PATH', realpath(APP_PATH . 'models/'));
defined('CLIENT_PATH') or define('CLIENT_PATH', APP_PATH . 'app/Client/'); defined('COMPONENT_PATH') or define('COMPONENT_PATH', realpath(APP_PATH . 'components/'));
defined('TASK_PATH') or define('TASK_PATH', APP_PATH . 'app/Async/');
defined('LISTENER_PATH') or define('LISTENER_PATH', APP_PATH . 'app/Listener/');
defined('KAFKA_PATH') or define('KAFKA_PATH', APP_PATH . 'app/Kafka/');
defined('RPC_CLIENT_PATH') or define('RPC_CLIENT_PATH', APP_PATH . 'app/Client/Rpc/');
defined('MODEL_PATH') or define('MODEL_PATH', APP_PATH . 'app/Model/');
/** /**
@@ -70,6 +63,15 @@ class Kiri
} }
/**
* @return Container
*/
public static function getContainer(): Container
{
return static::$container;
}
/** /**
* @param $alias * @param $alias
* @param array $array * @param array $array
@@ -136,25 +138,6 @@ class Kiri
} }
/**
* @param $port
* @return bool
* @throws Exception
*/
public static function port_already($port): bool
{
if (empty($port)) {
return false;
}
if (Kiri::getPlatform()->isLinux()) {
exec('netstat -tunlp | grep ' . $port, $output);
} else {
exec('lsof -i :' . $port . ' | grep -i "LISTEN"', $output);
}
return !empty($output);
}
/** /**
* @return Annotation * @return Annotation
* @throws Exception * @throws Exception
@@ -165,15 +148,6 @@ class Kiri
} }
/**
* @param $service
* @return string
*/
#[Pure] public static function listen($service): string
{
return sprintf('Check listen %s::%d -> ok', $service['host'], $service['port']);
}
/** /**
* @param $className * @param $className
@@ -196,6 +170,7 @@ class Kiri
} }
} }
/** /**
* @return string * @return string
* @throws Exception * @throws Exception
@@ -211,15 +186,6 @@ class Kiri
} }
/**
* @return bool
*/
public static function inCoroutine(): bool
{
return Coroutine::getCid() > 0;
}
/** /**
* @return Container * @return Container
*/ */
@@ -238,40 +204,6 @@ class Kiri
} }
/**
* @param $workerId
* @return mixed
* @throws Exception
*/
public static function setManagerId($workerId): mixed
{
if (empty($workerId) || static::isDocker()) {
return $workerId;
}
$tmpFile = storage($workerId . '.sock', 'pid/manager');
return self::writeFile($tmpFile, $workerId);
}
/**
* @param $workerId
* @return mixed
* @throws Exception
*/
public static function setProcessId($workerId): mixed
{
if (empty($workerId) || static::isDocker()) {
return $workerId;
}
$tmpFile = storage($workerId . '.sock', 'pid/process');
return self::writeFile($tmpFile, $workerId);
}
/** /**
* @return bool * @return bool
*/ */
@@ -285,39 +217,6 @@ class Kiri
} }
/**
* @param $workerId
* @return mixed
* @throws Exception
*/
public static function setWorkerId($workerId): mixed
{
if (empty($workerId) || static::isDocker()) {
return $workerId;
}
$tmpFile = storage($workerId . '.sock', 'pid/worker');
return self::writeFile($tmpFile, $workerId);
}
/**
* @param $workerId
* @return mixed
* @throws Exception
*/
public static function setTaskId($workerId): mixed
{
if (empty($workerId) || static::isDocker()) {
return $workerId;
}
$tmpFile = storage($workerId . '.sock', 'pid/task');
return self::writeFile($tmpFile, $workerId);
}
/** /**
* @param $fileName * @param $fileName
* @param $content * @param $content
@@ -330,7 +229,7 @@ class Kiri
if ($is_append !== null) { if ($is_append !== null) {
$params[] = $is_append; $params[] = $is_append;
} }
return !self::inCoroutine() ? file_put_contents(...$params) : Coroutine::writeFile(...$params); return !(Coroutine::getCid() > 0) ? file_put_contents(...$params) : Coroutine::writeFile(...$params);
} }
@@ -351,95 +250,6 @@ class Kiri
} }
/**
* @param $workerId
* @param bool $isWorker
* @throws Exception
*/
public static function clearProcessId($workerId, bool $isWorker = false)
{
clearstatcache();
$directory = $isWorker === true ? 'pid/worker' : 'pid/task';
if (!file_exists($file = storage($workerId, $directory))) {
return;
}
shell_exec('rm -rf ' . $file);
}
/**
* @param string|null $taskPid
* @throws Exception
*/
public static function clearTaskPid(string $taskPid = null)
{
if (empty($taskPid)) {
exec('rm -rf ' . storage(null, 'pid/task'));
} else {
static::clearProcessId($taskPid);
}
}
/**
* @param $taskPid
* @throws Exception
*/
public static function clearWorkerPid($taskPid = null)
{
if (empty($taskPid)) {
exec('rm -rf ' . storage(null, 'pid/worker'));
} else {
static::clearProcessId($taskPid, true);
}
}
/**
* @return Server|null
* @throws
*/
public static function getWebSocket(): ?\Swoole\Server
{
$server = static::app()->getSwoole();
if (!($server instanceof \Swoole\Server)) {
return null;
}
return $server;
}
/**
* @return false|string
* @throws Exception
*/
public static function getMasterPid(): bool|string
{
$pid = Kiri::app()->getSwoole()->setting['pid_file'];
return file_get_contents($pid);
}
/**
* @param int $fd
* @param $data
* @return mixed
* @throws Exception
*/
public static function push(int $fd, $data): mixed
{
$server = static::getWebSocket();
if (empty($server) || !$server->isEstablished($fd)) {
return false;
}
if (!is_string($data)) {
$data = Json::encode($data);
}
return $server->push($fd, $data);
}
/** /**
* @return mixed * @return mixed
*/ */
@@ -449,19 +259,6 @@ class Kiri
} }
/**
* @param string $class
* @param array $params
* @throws ReflectionException
* @throws Exception
*/
public static function async(string $class, array $params = [])
{
$manager = di(ServerManager::class);
$manager->task(new $class(...$params));
}
/** /**
* @param array $v1 * @param array $v1
* @param array $v2 * @param array $v2
@@ -486,19 +283,6 @@ class Kiri
} }
/**
* @param $process
* @throws Exception
*/
public static function shutdown($process): void
{
static::app()->getSwoole()->shutdown();
if ($process instanceof Process) {
$process->exit(0);
}
}
/** /**
* @param $tmp_name * @param $tmp_name
* @return string * @return string
@@ -536,34 +320,10 @@ class Kiri
} }
private static array $_autoload = [];
const PROCESS = 'process'; const PROCESS = 'process';
const TASK = 'task'; const TASK = 'task';
const WORKER = 'worker'; const WORKER = 'worker';
/**
* @param string $event
* @param null $data
* @return false|string
* @throws Exception
*/
public static function param(string $event, $data = NULL): bool|string
{
if (is_object($data)) {
if ($data instanceof ModelInterface || $data instanceof Collection) {
$data = $data->getAttributes();
} else {
$data = get_object_vars($data);
}
}
if (!is_array($data)) $data = ['data' => $data];
return json_encode(array_merge(['callback' => $event], $data));
}
/** /**
* @return string|null * @return string|null
*/ */
@@ -599,35 +359,6 @@ class Kiri
return static::getEnvironmental() == static::PROCESS; return static::getEnvironmental() == static::PROCESS;
} }
/**
* @param $class
* @param $file
*/
public static function setAutoload($class, $file)
{
if (isset(static::$_autoload[$class])) {
return;
}
static::$_autoload[$class] = $file;
include_once "Kiri.php";
}
/**
* @param $className
*/
public static function autoload($className)
{
if (!isset(static::$_autoload[$className])) {
return;
}
$file = static::$_autoload[$className];
require_once "Kiri.php";
}
} }
//spl_autoload_register([Kiri::class, 'autoload'], true, true);
Kiri::setContainer(new Container()); Kiri::setContainer(new Container());
+21 -21
View File
@@ -1,21 +1,21 @@
MIT License MIT License
Copyright (c) 2020 向林 Copyright (c) 2020 向林
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
+23 -23
View File
@@ -1,23 +1,23 @@
<?php <?php
function version($oldVersion, $newVersion): bool function version($oldVersion, $newVersion): bool
{ {
$first = explode('.', $oldVersion); $first = explode('.', $oldVersion);
$end = explode('.', $newVersion); $end = explode('.', $newVersion);
while (count($first) > 0) { while (count($first) > 0) {
$shift = (int)array_shift($first); $shift = (int)array_shift($first);
$endShift = (int)array_shift($end); $endShift = (int)array_shift($end);
if ($endShift == $shift) { if ($endShift == $shift) {
continue; continue;
} }
if ($endShift < $shift) { if ($endShift < $shift) {
return true; return TRUE;
} else { } else {
return false; return FALSE;
} }
} }
return false; return FALSE;
} }
var_dump(version('1.4.4','1.4.3')); var_dump(version('1.4.4', '1.4.3'));
+49 -47
View File
@@ -1,47 +1,49 @@
{ {
"name": "game-worker/kiri-core", "name": "game-worker/kiri-core",
"description": "test framework", "description": "test framework",
"authors": [ "authors": [
{ {
"name": "XiangLin", "name": "XiangLin",
"email": "as2252258@163.com" "email": "as2252258@163.com"
} }
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": ">=8.0", "php": ">=8.1",
"ext-json": "*", "ext-json": "*",
"ext-fileinfo": "*", "ext-fileinfo": "*",
"ext-pdo": "*", "ext-pdo": "*",
"ext-redis": "*", "ext-redis": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
"ext-libxml": "*", "ext-libxml": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-xml": "*", "ext-xml": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-openssl": "*", "ext-openssl": "*",
"symfony/console": "v5.3.10", "symfony/console": "~v5.3.10",
"psr/log": "1.*", "psr/log": "1.*",
"ext-sockets": "*", "composer-runtime-api": "^2.0",
"ext-pcntl": "*", "psr/container": "^2.0",
"ext-posix": "*", "psr/http-server-middleware": "1.0.1",
"composer-runtime-api": "^2.0", "game-worker/kiri-event": "~v2.0",
"swiftmailer/swiftmailer": "v6.3.*", "game-worker/kiri-di": "~v1.0",
"psr/container": "^2.0", "ext-inotify": "*"
"psr/http-server-middleware": "1.0.1", },
"game-worker/kiri-event": "v1.0", "autoload": {
"ext-inotify": "*" "psr-4": {
}, "Kiri\\": "kiri-engine/",
"autoload": { "Kiri\\Gateway\\": "kiri-gateway/",
"psr-4": { "Kiri\\Websocket\\": "kiri-websocket-server/",
"Kiri\\": "kiri-engine/", "Gii\\": "kiri-gii/",
"Gii\\": "kiri-gii/", "Kiri\\Annotation\\": "kiri-annotation/",
"Annotation\\": "kiri-note/" "Kiri\\Server\\": "kiri-server/",
}, "Kiri\\Task\\": "kiri-task/"
"files": [ },
"error.php", "files": [
"function.php" "Kiri.php",
] "error.php",
} "function.php"
} ]
}
}
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
define('SUCCESS', 0); define('SUCCESS', 0);
define('NO_AUTH', 401); define('NO_AUTH', 401);
define('ERROR_MESSAGES', [ define('ERROR_MESSAGES', [
SUCCESS => 'ok', SUCCESS => 'ok',
NO_AUTH => '' NO_AUTH => ''
]); ]);
if (!function_exists('message')) { if (!function_exists('message')) {
/** /**
* @param $code * @param $code
* @param $replace * @param $replace
* @param string $default * @param string $default
* @return mixed|string * @return mixed|string
*/ */
function message($code, $replace, $default = '') function message($code, $replace, $default = '')
{ {
if (!isset(ERROR_MESSAGES[$code])) { if (!isset(ERROR_MESSAGES[$code])) {
if (!empty($default)) { if (!empty($default)) {
return $default; return $default;
} }
return 'unknown error'; return 'unknown error';
} }
return sprintf(ERROR_MESSAGES[$code], $replace); return sprintf(ERROR_MESSAGES[$code], $replace);
} }
} }
+1241 -1155
View File
File diff suppressed because it is too large Load Diff
@@ -1,86 +1,86 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use ReflectionException; use ReflectionException;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Annotation * Class Annotation
* @package Annotation * @package Annotation
*/ */
class Annotation extends Component class Annotation extends Component
{ {
private Loader $_loader; private Loader $_loader;
/** /**
* *
*/ */
public function init(): void public function init(): void
{ {
$this->_loader = new Loader(); $this->_loader = new Loader();
} }
/** /**
* @return Loader * @return Loader
*/ */
public function getLoader(): Loader public function getLoader(): Loader
{ {
return $this->_loader; return $this->_loader;
} }
/** /**
* @param Loader $loader * @param Loader $loader
* @return Loader * @return Loader
*/ */
public function setLoader(Loader $loader): Loader public function setLoader(Loader $loader): Loader
{ {
return $this->_loader = $loader; return $this->_loader = $loader;
} }
/** /**
* @param object $class * @param object $class
* @throws ReflectionException * @throws ReflectionException
*/ */
public function injectProperty(object $class) public function injectProperty(object $class)
{ {
$this->_loader->injectProperty($class::class, $class); $this->_loader->injectProperty($class::class, $class);
} }
/** /**
* @param string $path * @param string $path
* @param string $namespace * @param string $namespace
* @param array $exclude * @param array $exclude
* @return static * @return static
* @throws Exception * @throws Exception
*/ */
public function read(string $path, string $namespace = 'App', array $exclude = []): static public function read(string $path, string $namespace = 'App', array $exclude = []): static
{ {
$this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude); $this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude);
return $this; return $this;
} }
/** /**
* @param string $dir * @param string $dir
* @param array $exclude * @param array $exclude
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function runtime(string $dir, array $exclude = []): array public function runtime(string $dir, array $exclude = []): array
{ {
return $this->_loader->loadByDirectory($dir, $exclude); return $this->_loader->loadByDirectory($dir, $exclude);
} }
} }
@@ -1,37 +1,37 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement '); defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement ');
/** /**
* Class Aspect * Class Aspect
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute
{ {
/** /**
* Aspect constructor. * Aspect constructor.
* @param string $aspect * @param string $aspect
*/ */
public function __construct(public string $aspect) public function __construct(public string $aspect)
{ {
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = ''): bool public function execute(mixed $class, mixed $method = ''): bool
{ {
return true; return true;
} }
} }
@@ -1,26 +1,27 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
/** /**
* Class Attribute * Class Attribute
* @package Annotation * @package Annotation
*/ */
abstract class Attribute implements IAnnotation abstract class Attribute implements IAnnotation
{ {
/** /**
* @param static $class * @param static $class
* @param mixed|string $method * @param mixed|string $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed #[\ReturnTypeWillChange]
{ public function execute(mixed $class, mixed $method = ''): mixed
// TODO: Implement execute() method. {
return true; // TODO: Implement execute() method.
} return true;
}
}
}
@@ -1,46 +1,46 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Kiri; use Kiri;
/** /**
* Class Event * Class Event
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Event extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Event extends Attribute
{ {
/** /**
* Event constructor. * Event constructor.
* @param string $name * @param string $name
* @param array $params * @param array $params
*/ */
public function __construct(public string $name, public array $params = []) public function __construct(public string $name, public array $params = [])
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
$pro = Kiri::getDi()->get(EventProvider::class); $pro = Kiri::getDi()->get(EventProvider::class);
if (is_string($class)) { if (is_string($class)) {
$class = Kiri::getDi()->get($class); $class = Kiri::getDi()->get($class);
} }
$pro->on($this->name, [$class, $method]); $pro->on($this->name, [$class, $method]);
return true; return true;
} }
} }
@@ -1,19 +1,19 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
interface IAnnotation interface IAnnotation
{ {
/** /**
* @param mixed $class * @param mixed $class
* @param mixed $method * @param mixed $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed; public function execute(mixed $class, mixed $method = ''): mixed;
} }
@@ -1,105 +1,104 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Core\Str; use Kiri\Core\Str;
use Kiri\Kiri; use Kiri;
use ReflectionException; use ReflectionException;
use ReflectionProperty; use ReflectionProperty;
/** /**
* Class Inject * Class Inject
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends Attribute #[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends Attribute
{ {
/** /**
* Inject constructor. * Inject constructor.
* @param string $value * @param string $value
* @param array $construct * @param array $construct
*/ */
public function __construct(public string $value, public array $construct = []) public function __construct(public string $value, public array $construct = [])
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws ReflectionException * @throws ReflectionException
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
if (!($method = $this->getProperty($class, $method))) { if (!($method = $this->getProperty($class, $method))) {
return false; return false;
} }
/** @var ReflectionProperty $class */ /** @var ReflectionProperty $class */
$injectValue = static::parseInjectValue(); $injectValue = static::parseInjectValue();
if ($method->isPrivate() || $method->isProtected()) { if ($method->isPrivate() || $method->isProtected()) {
$this->setter($class, $method, $injectValue); $this->setter($class, $method, $injectValue);
} else { } else {
$class->{$method->getName()} = $injectValue; $class->{$method->getName()} = $injectValue;
} }
return true; return true;
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @param $injectValue * @param $injectValue
*/ */
private function setter($class, $method, $injectValue) private function setter($class, $method, $injectValue)
{ {
$method = 'set' . ucfirst(Str::convertUnderline($method->getName())); $method = 'set' . ucfirst(Str::convertUnderline($method->getName()));
if (!method_exists($class, $method)) { if (!method_exists($class, $method)) {
return; return;
} }
$class->$method($injectValue); $class->$method($injectValue);
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @return ReflectionProperty|bool * @return ReflectionProperty|bool
* @throws ReflectionException */
*/ private function getProperty($class, $method): ReflectionProperty|bool
private function getProperty($class, $method): ReflectionProperty|bool {
{ if ($method instanceof ReflectionProperty && !$method->isStatic()) {
if ($method instanceof ReflectionProperty && !$method->isStatic()) { return $method;
return $method; }
} if (is_object($class)) $class = $class::class;
if (is_object($class)) $class = $class::class; $method = Kiri::getDi()->getClassReflectionProperty($class, $method);
$method = Kiri::getDi()->getClassReflectionProperty($class, $method); if (!$method || $method->isStatic()) {
if (!$method || $method->isStatic()) { return false;
return false; }
} return $method;
return $method; }
}
/**
/** * @return mixed
* @return mixed * @throws Exception
* @throws Exception */
*/ private function parseInjectValue(): mixed
private function parseInjectValue(): mixed {
{ if (!Kiri::app()->has($this->value)) {
if (!Kiri::app()->has($this->value)) { if (!empty($this->construct)) {
if (!empty($this->construct)) { return Kiri::getDi()->create($this->value, $this->construct);
return Kiri::getDi()->create($this->value, $this->construct); }
} return Kiri::getDi()->get($this->value);
return Kiri::getDi()->get($this->value); } else {
} else { return Kiri::app()->get($this->value);
return Kiri::app()->get($this->value); }
} }
}
}
}
@@ -1,243 +1,228 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use Kiri\Abstracts\BaseObject; use Kiri;
use Kiri\Kiri; use Kiri\Abstracts\Component;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
use Throwable; use Throwable;
/** /**
* Class Loader * Class Loader
* @package Annotation * @package Annotation
*/ */
class Loader extends BaseObject class Loader extends Component
{ {
private array $_classes = []; private array $_directory = [];
private array $_directory = []; private array $_methods = [];
private array $_property = []; /**
* @param $path
* @param $namespace
private array $_methods = []; * @throws Exception
*/
public function loader($path, $namespace)
/** {
* @param $path $this->_scanDir(new DirectoryIterator($path), $namespace);
* @param $namespace }
* @throws Exception
*/
public function loader($path, $namespace) /**
{ * @param string $class
$this->_scanDir(new DirectoryIterator($path), $namespace); * @param object $handler
} * @return $this
* @throws ReflectionException
/** * @throws Exception
* @param string $class */
* @param string $property public function injectProperty(string $class, object $handler): static
* @return \ReflectionProperty|array|null {
* @throws ReflectionException $di = Kiri::getDi();
*/
public function getProperty(string $class, string $property = ''): \ReflectionProperty|array|null $reflect = $di->getReflect($class);
{
return Kiri::getDi()->getClassReflectionProperty($class, $property); $di->propertyInject($reflect, $handler);
}
return $this;
}
/**
* @param string $class
* @param object $handler /**
* @return $this * @param string $class
* @throws ReflectionException * @param string $method
* @throws Exception * @return mixed
*/ */
public function injectProperty(string $class, object $handler): static public function getMethod(string $class, string $method = ''): array
{ {
$di = Kiri::getDi(); if (!isset($this->_methods[$class])) {
return [];
$reflect = $di->getReflect($class); }
$properties = $this->_methods[$class];
$di->propertyInject($reflect, $handler); if (!empty($method) && isset($properties[$method])) {
return $properties[$method];
return $this; }
} return $properties;
}
/**
* @param string $class /**
* @param string $method * @param DirectoryIterator $paths
* @return mixed * @param $namespace
*/ * @param array $exclude
public function getMethod(string $class, string $method = ''): array * @throws Exception
{ */
if (!isset($this->_methods[$class])) { public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = [])
return []; {
} foreach ($paths as $path) {
$properties = $this->_methods[$class]; if (function_exists('opcache_invalidate')) {
if (!empty($method) && isset($properties[$method])) { opcache_invalidate($path->getRealPath(), true);
return $properties[$method]; }
} if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
return $properties; continue;
} }
if ($this->inExclude($exclude, $path->getRealPath())) {
continue;
/** }
* @param DirectoryIterator $paths if ($path->isDir()) {
* @param $namespace $iterator = new DirectoryIterator($path->getRealPath());
* @param array $exclude $directory = rtrim($path->getRealPath(), '/');
* @throws Exception if (!isset($this->_directory[$directory])) {
*/ $this->_directory[$directory] = [];
public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = []) }
{ $this->_scanDir($iterator, $namespace);
foreach ($paths as $path) { } else {
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) { $this->readFile($path, $namespace);
continue; }
} }
if ($this->inExclude($exclude, $path->getRealPath())) { }
continue;
}
if ($path->isDir()) { /**
$iterator = new DirectoryIterator($path->getRealPath()); * @param DirectoryIterator $path
$directory = rtrim($path->getRealPath(), '/'); * @param $namespace
if (!isset($this->_directory[$directory])) { * @throws Exception
$this->_directory[$directory] = []; */
} private function readFile(DirectoryIterator $path, $namespace)
$this->_scanDir($iterator, $namespace); {
} else { try {
$this->readFile($path, $namespace); if ($path->getExtension() !== 'php') {
} return;
} }
} $replace = $this->getReflect($path, $namespace);
if (!$replace || !$replace->getAttributes(Target::class)) {
return;
/** }
* @param DirectoryIterator $path $this->appendFileToDirectory($path->getRealPath(), $replace->getName());
* @param $namespace } catch (Throwable $throwable) {
* @throws Exception $this->error(jTraceEx($throwable), 'throwable');
*/ }
private function readFile(DirectoryIterator $path, $namespace) }
{
try {
if ($path->getExtension() !== 'php') { /**
return; * @param DirectoryIterator $path
} * @param string $namespace
$replace = $this->getReflect($path, $namespace); * @return ReflectionClass|null
if (!$replace || !$replace->getAttributes(Target::class)) { */
return; private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass
} {
$this->appendFileToDirectory($path->getRealPath(), $replace->getName()); $class = $this->explodeFileName($path, $namespace);
} catch (Throwable $throwable) { if (!class_exists($class)) {
$this->error(jTraceEx($throwable), 'throwable'); return null;
} }
} return Kiri::getDi()->getReflect($class);
}
/**
* @param DirectoryIterator $path /**
* @param string $namespace * @param string $path
* @return ReflectionClass|null * @param array $exclude
* @throws ReflectionException * @return array
*/ * @throws Exception
private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass */
{ public function loadByDirectory(string $path, array $exclude = []): array
$class = $this->explodeFileName($path, $namespace); {
if (!class_exists($class)) { try {
return null; $path = '/' . trim($path, '/');
} $paths = [];
return Kiri::getDi()->getReflect($class); foreach ($this->_directory as $key => $_path) {
} $key = '/' . trim($key, '/');
if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) {
continue;
/** }
* @param string $path unset($this->_directory[$key]);
* @param array $exclude foreach ($_path as $item) {
* @return array $paths[] = $item;
* @throws Exception }
*/ }
public function loadByDirectory(string $path, array $exclude = []): array return $paths;
{ } catch (Throwable $exception) {
try { $this->addError($exception, 'throwable');
$path = '/' . trim($path, '/'); return [];
$paths = []; }
foreach ($this->_directory as $key => $_path) { }
$key = '/' . trim($key, '/');
if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) {
continue; /**
} * @param array $exclude
unset($this->_directory[$key]); * @param $path
foreach ($_path as $item) { * @return bool
$paths[] = $item; */
} private function inExclude(array $exclude, $path): bool
} {
return $paths; if (empty($exclude)) {
} catch (Throwable $exception) { return false;
$this->addError($exception, 'throwable'); }
return []; foreach ($exclude as $value) {
} if (str_starts_with($path, $value)) {
} return true;
}
}
/** return false;
* @param array $exclude }
* @param $path
* @return bool
*/ /**
private function inExclude(array $exclude, $path): bool * @param DirectoryIterator $path
{ * @param string $namespace
if (empty($exclude)) { * @return string
return false; */
} private function explodeFileName(DirectoryIterator $path, string $namespace): string
foreach ($exclude as $value) { {
if (str_starts_with($path, $value)) { $replace = str_replace(APP_PATH, '', $path->getRealPath());
return true;
} $replace = str_replace('.php', '', $replace);
} $replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace);
return false; $explode = explode('\\', $replace);
} array_shift($explode);
return $namespace . '\\' . implode('\\', $explode);
/** }
* @param DirectoryIterator $path
* @param string $namespace
* @return string /**
*/ * @param string $filePath
private function explodeFileName(DirectoryIterator $path, string $namespace): string * @param string $className
{ */
$replace = str_replace(APP_PATH, '', $path->getRealPath()); public function appendFileToDirectory(string $filePath, string $className)
{
$replace = str_replace('.php', '', $replace); $array = explode('/', $filePath);
$replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace); unset($array[count($array) - 1]);
$explode = explode('\\', $replace);
array_shift($explode); $array = '/' . trim(implode('/', $array), '/');
return $namespace . '\\' . implode('\\', $explode); $this->_directory[$array][] = $className;
} }
/** }
* @param string $filePath
* @param string $className
*/
public function appendFileToDirectory(string $filePath, string $className)
{
$array = explode('/', $filePath);
unset($array[count($array) - 1]);
$array = '/' . trim(implode('/', $array), '/');
$this->_directory[$array][] = $className;
}
}
@@ -1,31 +1,31 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Kiri\Kiri; use Kiri;
#[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends Attribute
{ {
/** /**
* @param string $class * @param string $class
*/ */
public function __construct(public string $class) public function __construct(public string $class)
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|string $method * @param mixed|string $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed public function execute(mixed $class, mixed $method = ''): mixed
{ {
Kiri::getDi()->mapping($this->class, $class); Kiri::getDi()->mapping($this->class, $class);
return parent::execute($class, $method); return parent::execute($class, $method);
} }
} }
@@ -1,34 +1,34 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Document * Class Document
* @package Annotation\Route * @package Annotation\Route
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Document extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Document extends Attribute
{ {
const INTEGER = 'int'; const INTEGER = 'int';
const STRING = 'string'; const STRING = 'string';
const BOOLEAN = 'bool'; const BOOLEAN = 'bool';
const FLOAT = 'float'; const FLOAT = 'float';
const ALIAS = [ const ALIAS = [
self::INTEGER => '整数', self::INTEGER => '整数',
self::STRING => '字符串', self::STRING => '字符串',
self::BOOLEAN => '布尔值', self::BOOLEAN => '布尔值',
self::FLOAT => '浮点', self::FLOAT => '浮点',
]; ];
public function __construct(array $request, array $response) public function __construct(array $request, array $response)
{ {
} }
} }
@@ -1,52 +1,53 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
use Http\Handler\Abstracts\MiddlewareManager; use Kiri\Message\Handler\Abstracts\MiddlewareManager;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
/** /**
* Class Middleware * Class Middleware
* @package Annotation\Route * @package Annotation\Route
*/ */
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends Attribute #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends Attribute
{ {
/** /**
* Interceptor constructor. * Interceptor constructor.
* @param string|array $middleware * @param string|array $middleware
* @throws * @throws
*/ */
public function __construct(public string|array $middleware) public function __construct(public string|array $middleware)
{ {
if (is_string($this->middleware)) { if (is_string($this->middleware)) {
$this->middleware = [$this->middleware]; $this->middleware = [$this->middleware];
} }
$array = []; $array = [];
foreach ($this->middleware as $value) { foreach ($this->middleware as $value) {
if (!in_array(MiddlewareInterface::class, class_implements($value))) { if (!in_array(MiddlewareInterface::class, class_implements($value))) {
throw new \Exception('The middleware'); throw new \Exception('The middleware');
} }
$array[] = $value; $array[] = $value;
} }
$this->middleware = $array; $this->middleware = $array;
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return $this * @return $this
*/ * @throws \ReflectionException
public function execute(mixed $class, mixed $method = null): mixed */
{ public function execute(mixed $class, mixed $method = null): mixed
MiddlewareManager::add($class, $method, $this->middleware); {
return parent::execute($class, $method); MiddlewareManager::add($class, $method, $this->middleware);
} return parent::execute($class, $method);
}
}
}
@@ -1,41 +1,41 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
use Http\Handler\Router; use Kiri\Message\Handler\Router;
use Kiri\Kiri; use Kiri;
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Route extends Attribute #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Route extends Attribute
{ {
/** /**
* Route constructor. * Route constructor.
* @param string $uri * @param string $uri
* @param string $method * @param string $method
* @param string $version * @param string $version
*/ */
public function __construct(public string $uri, public string $method, public string $version = 'v.1.0') public function __construct(public string $uri, public string $method, public string $version = 'v.1.0')
{ {
$this->uri = '/' . ltrim($this->uri, '/'); $this->uri = '/' . ltrim($this->uri, '/');
$this->method = strtoupper($this->method); $this->method = strtoupper($this->method);
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws \ReflectionException * @throws \ReflectionException
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
$di = Kiri::getDi()->get(Router::class); $di = Kiri::getDi()->get(Router::class);
$di->addRoute($this->method, $this->uri, $class . '@' . $method); $di->addRoute($this->method, $this->uri, $class . '@' . $method);
return parent::execute($class, $method); return parent::execute($class, $method);
} }
} }
@@ -1,31 +1,31 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Socket * Class Socket
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends Attribute
{ {
const CLOSE = 'CLOSE'; const CLOSE = 'CLOSE';
const MESSAGE = 'MESSAGE'; const MESSAGE = 'MESSAGE';
const HANDSHAKE = 'HANDSHAKE'; const HANDSHAKE = 'HANDSHAKE';
/** /**
* Socket constructor. * Socket constructor.
* @param string $event * @param string $event
* @param string|null $uri * @param string|null $uri
* @param string $version * @param string $version
*/ */
public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0') public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0')
{ {
} }
} }
@@ -1,28 +1,28 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
/** /**
* Class Target * Class Target
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_CLASS)] class Target extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Target extends Attribute
{ {
const WORKER = 'worker'; const WORKER = 'worker';
const ALL = 'any'; const ALL = 'any';
const PROCESS = 'process'; const PROCESS = 'process';
const TASK = 'task'; const TASK = 'task';
/** /**
* @param string $only * @param string $only
*/ */
public function __construct(string $only = Target::ALL) public function __construct(string $only = Target::ALL)
{ {
} }
} }
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace Kiri\Abstracts;
abstract class AbstractServer extends Component
{
public string $name = 'http';
}
+453 -460
View File
@@ -1,460 +1,453 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/10/7 0007 * Date: 2018/10/7 0007
* Time: 2:13 * Time: 2:13
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Annotation\Annotation as SAnnotation; use Database\Connection;
use Database\Connection; use Exception;
use Exception; use Kafka\KafkaProvider;
use Http\Handler\Router; use Kiri;
use Kiri\Events\OnBeforeCommandExecute; use Kiri\Annotation\Annotation as SAnnotation;
use Server\Server; use Kiri\Async;
use Kafka\KafkaProvider; use Kiri\Cache\Redis;
use Kiri\Async; use Kiri\Di\LocalService;
use Kiri\Cache\Redis; use Kiri\Error\{ErrorHandler, Logger};
use Kiri\Di\LocalService; use Kiri\Exception\{InitException, NotFindClassException};
use Kiri\Error\ErrorHandler; use Kiri\Message\Handler\Router;
use Kiri\Error\Logger; use Kiri\Server\{Server, ServerManager};
use Kiri\Events\EventProvider; use Kiri\Task\AsyncTaskExecute;
use Kiri\Exception\InitException; use Kiri\Task\OnTaskInterface;
use Kiri\Exception\NotFindClassException; use ReflectionException;
use Kiri\Kiri; use Swoole\Table;
use ReflectionException;
use Server\ServerManager; /**
use Server\Contract\OnTaskInterface; * Class BaseApplication
use Swoole\Table; * @package Kiri\Base
*/
/** abstract class BaseApplication extends Component
* Class BaseApplication {
* @package Kiri\Kiri\Base
*/ use TraitApplication;
abstract class BaseApplication extends Component
{
/**
use TraitApplication; * @var string
*/
public string $storage = APP_PATH . 'storage';
/**
* @var string public string $envPath = APP_PATH . '.env';
*/
public string $storage = APP_PATH . 'storage'; /**
* Init constructor.
public string $envPath = APP_PATH . '.env'; *
*
/** * @throws
* Init constructor. */
* public function __construct()
* {
* @throws Kiri::init($this);
*/
public function __construct() $config = sweep(APP_PATH . '/config');
{
Kiri::init($this); $this->moreComponents();
$this->parseInt($config);
$config = sweep(APP_PATH . '/config'); $this->parseEvents($config);
$this->initErrorHandler();
$this->moreComponents(); $this->enableEnvConfig();
$this->parseInt($config); $this->mapping($config['mapping'] ?? []);
$this->parseEvents($config);
$this->initErrorHandler(); parent::__construct();
$this->enableEnvConfig(); }
$this->mapping($config['mapping'] ?? []);
parent::__construct(); /**
} * @param array $mapping
*/
public function mapping(array $mapping)
/** {
* @param array $mapping $di = Kiri::getDi();
*/ foreach ($mapping as $interface => $class) {
public function mapping(array $mapping) $di->mapping($interface, $class);
{ }
$di = Kiri::getDi(); }
foreach ($mapping as $interface => $class) {
$di->mapping($interface, $class);
} /**
} * @return array
*/
public function enableEnvConfig(): array
/** {
* @return array if (!file_exists($this->envPath)) {
*/ return [];
public function enableEnvConfig(): array }
{ $lines = $this->readLinesFromFile($this->envPath);
if (!file_exists($this->envPath)) { foreach ($lines as $line) {
return []; if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
} [$key, $value] = explode('=', $line);
$lines = $this->readLinesFromFile($this->envPath); putenv(trim($key) . '=' . trim($value));
foreach ($lines as $line) { }
if (!$this->isComment($line) && $this->looksLikeSetter($line)) { }
[$key, $value] = explode('=', $line); return $lines;
putenv(trim($key) . '=' . trim($value)); }
}
}
return $lines; /**
} * Read lines from the file, auto detecting line endings.
*
* @param string $filePath
/** *
* Read lines from the file, auto detecting line endings. * @return array
* */
* @param string $filePath protected function readLinesFromFile(string $filePath): array
* {
* @return array // Read file into an array of lines with auto-detected line endings
*/ $autodetect = ini_get('auto_detect_line_endings');
protected function readLinesFromFile(string $filePath): array ini_set('auto_detect_line_endings', '1');
{ $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Read file into an array of lines with auto-detected line endings ini_set('auto_detect_line_endings', $autodetect);
$autodetect = ini_get('auto_detect_line_endings');
ini_set('auto_detect_line_endings', '1'); return $lines;
$lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); }
ini_set('auto_detect_line_endings', $autodetect);
/**
return $lines; * Determine if the line in the file is a comment, e.g. begins with a #.
} *
* @param string $line
/** *
* Determine if the line in the file is a comment, e.g. begins with a #. * @return bool
* */
* @param string $line protected function isComment(string $line): bool
* {
* @return bool $line = ltrim($line);
*/
protected function isComment(string $line): bool return isset($line[0]) && $line[0] === '#';
{ }
$line = ltrim($line);
/**
return isset($line[0]) && $line[0] === '#'; * Determine if the given line looks like it's setting a variable.
} *
* @param string $line
/** *
* Determine if the given line looks like it's setting a variable. * @return bool
* */
* @param string $line protected function looksLikeSetter(string $line): bool
* {
* @return bool return str_contains($line, '=');
*/ }
protected function looksLikeSetter(string $line): bool
{
return str_contains($line, '='); /**
} * @param $config
*
* @throws
/** */
* @param $config public function parseInt($config)
* {
* @throws Config::sets($config);
*/ if ($storage = Config::get('storage', 'storage')) {
public function parseInt($config) if (!str_contains($storage, APP_PATH)) {
{ $storage = APP_PATH . $storage . '/';
Config::sets($config); }
if ($storage = Config::get('storage', 'storage')) { if (!is_dir($storage)) {
if (!str_contains($storage, APP_PATH)) { mkdir($storage);
$storage = APP_PATH . $storage . '/'; }
} if (!is_dir($storage) || !is_writeable($storage)) {
if (!is_dir($storage)) { throw new InitException("Directory {$storage} does not have write permission");
mkdir($storage); }
} }
if (!is_dir($storage) || !is_writeable($storage)) { }
throw new InitException("Directory {$storage} does not have write permission");
}
} /**
} * @param $name
* @return mixed
* @throws ReflectionException
/** * @throws NotFindClassException
* @param $name * @throws Exception
* @return mixed */
* @throws ReflectionException public function __get($name): mixed
* @throws NotFindClassException {
* @throws Exception if ($this->has($name)) {
*/ return $this->get($name);
public function __get($name): mixed }
{ return parent::__get($name); // TODO: Change the autogenerated stub
if ($this->has($name)) { }
return $this->get($name);
}
return parent::__get($name); // TODO: Change the autogenerated stub /**
} * @param $config
*
* @throws
/** */
* @param $config public function parseEvents($config)
* {
* @throws if (!isset($config['events']) || !is_array($config['events'])) {
*/ return;
public function parseEvents($config) }
{ foreach ($config['events'] as $key => $value) {
if (!isset($config['events']) || !is_array($config['events'])) { if (is_string($value)) {
return; $value = Kiri::createObject($value);
} }
foreach ($config['events'] as $key => $value) { $this->addEvent($key, $value);
if (is_string($value)) { }
$value = Kiri::createObject($value); }
}
$this->addEvent($key, $value);
} /**
} * @param OnTaskInterface $execute
* @throws ReflectionException|Exception
*/
/** public function task(OnTaskInterface $execute): void
* @param OnTaskInterface $execute {
* @throws ReflectionException di(AsyncTaskExecute::class)->execute($execute);
*/ }
public function task(OnTaskInterface $execute): void
{
di(ServerManager::class)->task($execute); /**
} * @param $key
* @param $value
* @throws InitException
/** * @throws Exception
* @param $key */
* @param $value private function addEvent($key, $value): void
* @throws InitException {
* @throws Exception if ($value instanceof \Closure || is_object($value)) {
*/ $this->getEventProvider()->on($key, $value, 0);
private function addEvent($key, $value): void return;
{ }
$eventProvider = di(EventProvider::class);
if ($value instanceof \Closure || is_object($value)) {
$eventProvider->on($key, $value, 0); if (is_array($value)) {
return; if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
} $this->getEventProvider()->on($key, $value, 0);
return;
}
if (is_array($value)) {
if (is_object($value[0]) && !($value[0] instanceof \Closure)) { if (is_string($value[0])) {
$eventProvider->on($key, $value, 0); $value[0] = Kiri::createObject($value[0]);
return; $this->getEventProvider()->on($key, $value, 0);
} return;
}
if (is_string($value[0])) {
$value[0] = Kiri::createObject($value[0]);
$eventProvider->on($key, $value, 0); foreach ($value as $item) {
return; if (!is_callable($item, true)) {
} throw new InitException("Class does not hav callback.");
}
$this->getEventProvider()->on($key, $item, 0);
foreach ($value as $item) { }
if (!is_callable($item, true)) { }
throw new InitException("Class does not hav callback.");
} }
$eventProvider->on($key, $item, 0);
}
} /**
* @param $name
} * @return mixed
* @throws Exception
*/
/** public function clone($name): mixed
* @param $name {
* @return mixed return clone $this->get($name);
* @throws Exception }
*/
public function clone($name): mixed /**
{ *
return clone $this->get($name); * @throws Exception
} */
public function initErrorHandler()
/** {
* $this->get('error')->register();
* @throws Exception }
*/
public function initErrorHandler()
{ /**
$this->get('error')->register(); * @param $name
} * @return mixed
* @throws
*/
/** public function get($name): mixed
* @param $name {
* @return mixed return di(LocalService::class)->get($name);
* @throws }
*/
public function get($name): mixed
{ /**
return di(LocalService::class)->get($name); * @return mixed
} */
public function getLocalIps(): mixed
{
/** return swoole_get_local_ip();
* @return mixed }
*/
public function getLocalIps(): mixed /**
{ * @return mixed
return swoole_get_local_ip(); */
} public function getFirstLocal(): mixed
{
/** return current($this->getLocalIps());
* @return mixed }
*/
public function getFirstLocal(): mixed
{ /**
return current($this->getLocalIps()); * @return Logger
} * @throws
*/
public function getLogger(): Logger
/** {
* @return Logger return $this->get('logger');
* @throws }
*/
public function getLogger(): Logger
{ /**
return $this->get('logger'); * @return \Redis|Redis
} * @throws
*/
public function getRedis(): Redis|\Redis
/** {
* @return \Redis|Redis return Kiri::getDi()->get(Redis::class);
* @throws }
*/
public function getRedis(): Redis|\Redis /**
{ * @param $ip
return Kiri::getDi()->get(Redis::class); * @return bool
} */
public function isLocal($ip): bool
/** {
* @param $ip return $this->getFirstLocal() == $ip;
* @return bool }
*/
public function isLocal($ip): bool
{ /**
return $this->getFirstLocal() == $ip; * @return ErrorHandler
} * @throws
*/
public function getError(): ErrorHandler
/** {
* @return ErrorHandler return $this->get('error');
* @throws }
*/
public function getError(): ErrorHandler
{ /**
return $this->get('error'); * @param $name
} * @return Table
* @throws
*/
/** public function getTable($name): Table
* @param $name {
* @return Table return $this->get($name);
* @throws }
*/
public function getTable($name): Table
{ /**
return $this->get($name); * @return Config
} * @throws
*/
public function getConfig(): Config
/** {
* @return Config return $this->get('config');
* @throws }
*/
public function getConfig(): Config
{ /**
return $this->get('config'); * @return Router
} * @throws
*/
public function getRouter(): Router
/** {
* @return Router return Kiri::getDi()->get(Router::class);
* @throws }
*/
public function getRouter(): Router
{ /**
return Kiri::getDi()->get(Router::class); * @return Server
} * @throws
*/
public function getServer(): Server
/** {
* @return Server return Kiri::getDi()->get(Server::class);
* @throws }
*/
public function getServer(): Server
{ /**
return $this->get('server'); * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
} * @throws
*/
public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
/** {
* @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null return di(ServerManager::class)->getServer();
* @throws }
*/
public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
{ /**
return di(ServerManager::class)->getServer(); * @return SAnnotation
} * @throws
*/
public function getAnnotation(): SAnnotation
/** {
* @return SAnnotation return $this->get('Annotation');
* @throws }
*/
public function getAnnotation(): SAnnotation
{ /**
return $this->get('annotation'); * @return Async
} * @throws
*/
public function getAsync(): Async
/** {
* @return Async return $this->get('async');
* @throws }
*/
public function getAsync(): Async
{ /**
return $this->get('async'); * @param $array
} */
private function setComponents($array): void
{
di(LocalService::class)->setComponents($array);
/** }
* @param $array
*/
private function setComponents($array): void /**
{ * @param $id
di(LocalService::class)->setComponents($array); * @param $definition
} */
public function set($id, $definition): void
{
/** di(LocalService::class)->set($id, $definition);
* @param $id }
* @param $definition
*/
public function set($id, $definition): void /**
{ * @param $id
di(LocalService::class)->set($id, $definition); * @return bool
} */
public function has($id): bool
{
/** return di(LocalService::class)->has($id);
* @param $id }
* @return bool
*/
public function has($id): bool /**
{ * @throws Exception
return di(LocalService::class)->has($id); */
} protected function moreComponents(): void
{
$this->setComponents([
/** 'error' => ['class' => ErrorHandler::class],
* @throws Exception 'config' => ['class' => Config::class],
*/ 'logger' => ['class' => Logger::class],
protected function moreComponents(): void 'Annotation' => ['class' => SAnnotation::class],
{ 'databases' => ['class' => Connection::class],
$this->setComponents([ 'async' => ['class' => Async::class],
'error' => ['class' => ErrorHandler::class], 'kafka-container' => ['class' => KafkaProvider::class],
'config' => ['class' => Config::class], ]);
'logger' => ['class' => Logger::class], }
'annotation' => ['class' => SAnnotation::class], }
'databases' => ['class' => Connection::class],
'jwt' => ['class' => Jwt::class],
'async' => ['class' => Async::class],
'kafka-container' => ['class' => KafkaProvider::class],
]);
}
}
+13 -13
View File
@@ -1,13 +1,13 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Swoole\Coroutine; use Swoole\Coroutine;
abstract class BaseContext abstract class BaseContext
{ {
protected static array $pool = []; protected static array $pool = [];
} }
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
use Kiri\Core\Json; use Kiri\Core\Json;
/** /**
* Class BaseGoto * Class BaseGoto
* @package Kiri\Abstracts * @package Kiri\Abstracts
*/ */
class BaseGoto extends Component class BaseGoto extends Component
{ {
/** /**
* @param string $message * @param string $message
* @param int $statusCode * @param int $statusCode
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function end(string $message, int $statusCode = 200): mixed public function end(string $message, int $statusCode = 200): mixed
{ {
throw new Exception(Json::to(12350, $message), $statusCode); throw new Exception(Json::to(12350, $message), $statusCode);
} }
} }
-243
View File
@@ -1,243 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: whwyy
* Date: 2018/3/30 0030
* Time: 14:10
*/
declare(strict_types=1);
namespace Kiri\Abstracts;
use Exception;
use JetBrains\PhpStorm\Pure;
use Kiri\Kiri;
use Swoole\Coroutine;
/**
* Class BaseObject
* @package Kiri\Kiri\Base
*/
class BaseObject implements Configure
{
/**
* BaseAbstract constructor.
*
* @param array $config
* @throws Exception
*/
public function __construct(array $config = [])
{
if (!empty($config) && is_array($config)) {
Kiri::configure($this, $config);
}
}
/**
* @throws Exception
*/
public function init()
{
}
/**
* @param array|callable $callback
* @param object $scope
*/
public function async_create(array|callable $callback, object $scope)
{
Coroutine::create($callback, $scope);
}
/**
* @return string
*/
#[Pure] public static function className(): string
{
return static::class;
}
/**
* @param $name
* @param $value
*
* @throws Exception
*/
public function __set($name, $value)
{
$method = 'set' . ucfirst($name);
if (method_exists($this, $method)) {
$this->{$method}($value);
} else {
throw new Exception('The set name ' . $name . ' not find in class ' . static::class);
}
}
/**
* @param $name
*
* @return mixed
* @throws Exception
*/
public function __get($name): mixed
{
$method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->$method();
} else {
throw new Exception('The get name ' . $name . ' not find in class ' . static::class);
}
}
/**
* @param $message
* @param string $model
* @return bool
* @throws Exception
*/
public function addError($message, string $model = 'app'): bool
{
if ($message instanceof \Throwable) {
$this->error(jTraceEx($message));
} else {
if (!is_string($message)) {
$message = json_encode($message, JSON_UNESCAPED_UNICODE);
}
$this->error($message);
}
return FALSE;
}
/**
* @return Logger
* @throws Exception
*/
private function logger(): Logger
{
return Kiri::getDi()->get(Logger::class);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function debug(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[35m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->debug($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function info(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[34m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->info($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function success(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[36m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->notice($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function warning(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[33m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->critical($message, $context);
}
/**
* @param mixed $message
* @param null $method
* @param null $file
* @throws Exception
*/
public function error(mixed $message, $method = null, $file = null)
{
if ($message instanceof \Throwable) {
$message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile();
}
$content = (empty($method) ? '' : $method . ': ') . $message;
$message = "\033[41;37m" . $content . "\033[0m";
if (!empty($file)) {
$message .= PHP_EOL . "\03341;37m[" . $file . "\033[0m";
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->error($message, $context);
}
}
+10 -10
View File
@@ -1,10 +1,10 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
abstract class Command extends Component abstract class Command extends Component
{ {
} }
+227 -55
View File
@@ -1,55 +1,227 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/3/30 0030 * Date: 2018/3/30 0030
* Time: 14:28 * Time: 14:28
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
use JetBrains\PhpStorm\Pure;
use JetBrains\PhpStorm\Pure; use Kiri\Di\Container;
use Kiri\Exception\ComponentException; use Kiri\Events\EventDispatch;
use Kiri\Kiri; use Kiri\Events\EventProvider;
use Kiri;
/** use Psr\Container\ContainerExceptionInterface;
* Class Component use Psr\Container\ContainerInterface;
* @package Kiri\Kiri\Base use Psr\Container\NotFoundExceptionInterface;
*/
class Component extends BaseObject /**
{ * Class Component
* @package Kiri\Base
*/
/** class Component implements Configure
* @param $name {
* @param $value
* @throws Exception
*/ /**
public function __set($name, $value) * BaseAbstract constructor.
{ *
if (property_exists($this, $name)) { * @param array $config
$this->$name = $value; * @throws Exception
} else { */
parent::__set($name, $value); public function __construct(array $config = [])
} {
} if (!empty($config) && is_array($config)) {
Kiri::configure($this, $config);
}
/** }
* @param $name
* @return mixed
* @throws Exception /**
*/ * @return Container|ContainerInterface
public function __get($name): mixed */
{ #[Pure] public function getContainer(): ContainerInterface|Container
if (property_exists($this, $name)) { {
return $this->$name ?? null; return Kiri::getDi();
} else { }
return parent::__get($name);
}
} /**
} * @return EventProvider
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getEventProvider(): EventProvider
{
return $this->getContainer()->get(EventProvider::class);
}
/**
* @return EventDispatch
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
protected function getEventDispatch(): EventDispatch
{
return $this->getContainer()->get(EventDispatch::class);
}
/**
* @throws Exception
*/
public function init()
{
}
/**
* @return string
*/
#[Pure] public static function className(): string
{
return static::class;
}
/**
* @param $message
* @param string $model
* @return bool
* @throws Exception
*/
public function addError($message, string $model = 'app'): bool
{
if ($message instanceof \Throwable) {
$this->error($message = jTraceEx($message));
} else {
if (!is_string($message)) {
$message = json_encode($message, JSON_UNESCAPED_UNICODE);
}
$this->error($message);
}
Kiri::app()->getLogger()->fail($message, $model);
return FALSE;
}
/**
* @return Logger
* @throws Exception
*/
protected function logger(): Logger
{
return Kiri::getDi()->get(Logger::class);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function debug(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->debug($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function info(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->info($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function success(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->notice($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function warning(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->critical($message, $context);
}
/**
* @param mixed $message
* @param null $method
* @param null $file
* @throws Exception
*/
public function error(mixed $message, $method = null, $file = null)
{
if ($message instanceof \Throwable) {
$message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile();
}
$context = [];
if (is_string($method)) {
$message = (empty($method) ? '' : $method . ': ') . $message;
} else {
if (is_null($method)) {
$method = [];
}
$context = $method;
}
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->error($message, $context);
}
}
+128 -124
View File
@@ -1,124 +1,128 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/5/24 0024 * Date: 2018/5/24 0024
* Time: 11:50 * Time: 11:50
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Kiri\Exception\ConfigException;
use Kiri\Exception\ConfigException;
use Kiri\Kiri;
/**
* Class Config
/** * @package Kiri\Base
* Class Config */
* @package Kiri\Kiri\Base class Config extends Component
*/ {
class Config extends Component
{ const ERROR_MESSAGE = 'The not find %s in app configs.';
const ERROR_MESSAGE = 'The not find %s in app configs.'; protected static mixed $data = [];
protected mixed $data = [];
/**
* @return mixed
/** */
* @return mixed public static function getData(): mixed
*/ {
public function getData(): mixed return static::$data;
{ }
return $this->data;
}
/**
* @param $key
/** * @param $value
* @param $key * @return mixed
* @param $value */
* @return mixed public static function setData($key, $value): mixed
*/ {
public function setData($key, $value): mixed return static::$data[$key] = $value;
{ }
return $this->data[$key] = $value;
}
/**
* @param array $configs
/** */
* @param array $configs public static function sets(array $configs)
* @throws Exception {
*/ if (empty($configs)) {
public static function sets(array $configs) return;
{ }
$config = Kiri::app()->getConfig(); static::$data = $configs;
if (empty($configs)) { }
return;
} /**
$config->data = $configs; * @param $key
} * @param bool $try
* @param mixed|null $default
/** * @return mixed
* @param $key * @throws ConfigException
* @param bool $try */
* @param mixed|null $default public static function get($key, mixed $default = null, bool $try = FALSE): mixed
* @return mixed {
* @throws $instance = static::$data;
*/ if (!str_contains($key, '.')) {
public static function get($key, mixed $default = null, bool $try = FALSE): mixed return $instance[$key] ?? $default;
{ }
$instance = Kiri::app()->getConfig()->getData(); foreach (explode('.', $key) as $value) {
if (!str_contains($key, '.')) { if (empty($value)) {
return $instance[$key] ?? $default; continue;
} }
foreach (explode('.', $key) as $value) { if (!isset($instance[$value])) {
if (empty($value)) { if ($try) {
continue; throw new ConfigException(sprintf(self::ERROR_MESSAGE, $key));
} }
if (!isset($instance[$value])) { return $default;
if ($try) { }
throw new ConfigException(sprintf(self::ERROR_MESSAGE, $key)); if (!is_array($instance[$value])) {
} return $instance[$value];
return $default; }
} $instance = $instance[$value];
if (!is_array($instance[$value])) { }
return $instance[$value]; return empty($instance) ? $default : $instance;
} }
$instance = $instance[$value];
} /**
return empty($instance) ? $default : $instance; * @param $key
} * @param $value
* @return mixed
/** */
* @param $key public static function set($key, $value): mixed
* @param $value {
* @return mixed $explode = explode('.', $key);
* @throws Exception $parent = &static::$data;
*/ foreach ($explode as $item) {
public static function set($key, $value): mixed if (!isset($parent[$item])) {
{ $parent[$item] = [];
$config = Kiri::app()->getConfig(); }
return $config->setData($key, $value); $parent = &$parent[$item];
} }
$parent = $value;
/**
* @param $key unset($parent);
* @param bool $must_not_null
* @return bool return static::$data;
* @throws Exception }
*/
public static function has($key, bool $must_not_null = false): bool /**
{ * @param $key
$config = Kiri::app()->getConfig(); * @param bool $must_not_null
if (!isset($config->data[$key])) { * @return bool
return false; */
} public static function has($key, bool $must_not_null = false): bool
$config = $config->data[$key]; {
if ($must_not_null === false) { if (!isset(static::$data[$key])) {
return true; return false;
} }
return !empty($config); $config = static::$data[$key];
} if ($must_not_null === false) {
return true;
} }
return !empty($config);
}
}
+18 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/3/30 0030 * Date: 2018/3/30 0030
* Time: 14:11 * Time: 14:11
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
/** /**
* Interface Configure * Interface Configure
* @package Kiri\Kiri\Base * @package Kiri\Base
*/ */
interface Configure interface Configure
{ {
} }
+26 -26
View File
@@ -1,26 +1,26 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Kiri\Core\Dtl; use Kiri\Core\Dtl;
/** /**
* Interface IListener * Interface IListener
* @package Kiri\Abstracts * @package Kiri\Abstracts
*/ */
interface IListener interface IListener
{ {
/** /**
* @param Dtl $dtl * @param Dtl $dtl
* @return mixed * @return mixed
*/ */
public function execute(Dtl $dtl): mixed; public function execute(Dtl $dtl): mixed;
} }
+111 -111
View File
@@ -1,111 +1,111 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
class Input class Input
{ {
private array $_argv = []; private array $_argv = [];
private string $_command = ''; private string $_command = '';
/** /**
* Input constructor. * Input constructor.
* @param $argv * @param $argv
* @throws * @throws
*/ */
public function __construct($argv) public function __construct($argv)
{ {
$this->_argv = $this->resolve($argv); $this->_argv = $this->resolve($argv);
} }
/** /**
* @return string * @return string
*/ */
public function getCommandName(): string public function getCommandName(): string
{ {
return $this->_command; return $this->_command;
} }
/** /**
* @param $key * @param $key
* @param null $default * @param null $default
* @return mixed * @return mixed
*/ */
public function get($key, $default = null): mixed public function get($key, $default = null): mixed
{ {
return $this->_argv[$key] ?? $default; return $this->_argv[$key] ?? $default;
} }
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
public function exists($key): bool public function exists($key): bool
{ {
return isset($this->_argv[$key]); return isset($this->_argv[$key]);
} }
/** /**
* @param $key * @param $key
* @param $value * @param $value
* @return $this * @return $this
*/ */
public function set($key, $value): static public function set($key, $value): static
{ {
$this->_argv[$key] = $value; $this->_argv[$key] = $value;
return $this; return $this;
} }
/** /**
* @return false|string * @return false|string
*/ */
public function toJson(): bool|string public function toJson(): bool|string
{ {
return json_encode($this->_argv, JSON_UNESCAPED_UNICODE); return json_encode($this->_argv, JSON_UNESCAPED_UNICODE);
} }
/** /**
* @param $parameters * @param $parameters
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function resolve($parameters): array public function resolve($parameters): array
{ {
$arrays = []; $arrays = [];
$parameters = array_slice($parameters, 1); $parameters = array_slice($parameters, 1);
if (empty($parameters)) { if (empty($parameters)) {
return $arrays; return $arrays;
} }
$this->_command = array_shift($parameters); $this->_command = array_shift($parameters);
foreach ($parameters as $parameter) { foreach ($parameters as $parameter) {
$explode = explode('=', $parameter); $explode = explode('=', $parameter);
if (count($explode) < 2) { if (count($explode) < 2) {
continue; continue;
} }
$arrays[array_shift($explode)] = current($explode); $arrays[array_shift($explode)] = current($explode);
} }
return $arrays; return $arrays;
} }
/** /**
* @return string * @return string
*/ */
public function getCommand(): string public function getCommand(): string
{ {
return $this->_command; return $this->_command;
} }
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
interface Kernel interface Kernel
{ {
/** /**
* @return array * @return array
*/ */
public function getCommands(): array; public function getCommands(): array;
} }
+18 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
/** /**
* Class Listener * Class Listener
* @package Kiri\Abstracts * @package Kiri\Abstracts
* 监听的名称 * 监听的名称
*/ */
abstract class Listener extends Component implements IListener abstract class Listener extends Component implements IListener
{ {
} }
+229 -201
View File
@@ -1,201 +1,229 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Annotation\Inject; use DirectoryIterator;
use Exception; use Exception;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Psr\Log\LoggerInterface; use Kiri;
use Server\Events\OnWorkerStop; use Kiri\Server\Events\OnWorkerStop;
use Psr\Log\LoggerInterface;
use ReflectionException;
/**
*
*/ /**
class Logger implements LoggerInterface *
{ */
class Logger implements LoggerInterface
const EMERGENCY = 'emergency'; {
const ALERT = 'alert';
const CRITICAL = 'critical'; const EMERGENCY = 'emergency';
const ERROR = 'error'; const ALERT = 'alert';
const WARNING = 'warning'; const CRITICAL = 'critical';
const NOTICE = 'notice'; const ERROR = 'error';
const INFO = 'info'; const WARNING = 'warning';
const DEBUG = 'debug'; const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
/**
* @var EventProvider
*/ private array $_loggers = [];
#[Inject(EventProvider::class)]
public EventProvider $eventProvider;
const LOGGER_LEVELS = [Logger::EMERGENCY, Logger::ALERT, Logger::CRITICAL, Logger::ERROR, Logger::WARNING, Logger::NOTICE, Logger::INFO, Logger::DEBUG];
private array $_loggers = [];
/**
const LOGGER_LEVELS = [Logger::EMERGENCY, Logger::ALERT, Logger::CRITICAL, Logger::ERROR, Logger::WARNING, Logger::NOTICE, Logger::INFO, Logger::DEBUG]; * @return void
* @throws ReflectionException
*/
/** public function init()
* 监听事件 {
*/ Kiri::getDi()->get(EventProvider::class)->on(OnWorkerStop::class, [$this, 'onAfterRequest']);
public function init() }
{
$this->eventProvider->on(OnWorkerStop::class, [$this, 'onAfterRequest']);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message *
* @param array $context * 紧急情况
* @throws ConfigException */
* public function emergency($message, array $context = [])
* 紧急情况 {
*/ // TODO: Implement emergency() method.
public function emergency($message, array $context = []) $this->log(Logger::EMERGENCY, $message, $context);
{ }
// TODO: Implement emergency() method.
$this->log(Logger::EMERGENCY, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message *
* @param array $context * 应该警惕的
* @throws ConfigException */
* public function alert($message, array $context = [])
* 应该警惕的 {
*/ // TODO: Implement alert() method.
public function alert($message, array $context = []) $this->log(Logger::ALERT, $message, $context);
{ }
// TODO: Implement alert() method.
$this->log(Logger::ALERT, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message *
* @param array $context * 关键性的日志
* @throws ConfigException */
* public function critical($message, array $context = [])
* 关键性的日志 {
*/ // TODO: Implement critical() method.
public function critical($message, array $context = []) $this->log(Logger::CRITICAL, $message, $context);
{ }
// TODO: Implement critical() method.
$this->log(Logger::CRITICAL, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function error($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement error() method.
public function error($message, array $context = []) $this->log(Logger::ERROR, $message, $context);
{ }
// TODO: Implement error() method.
$this->log(Logger::ERROR, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function warning($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement warning() method.
public function warning($message, array $context = []) $this->log(Logger::WARNING, $message, $context);
{ }
// TODO: Implement warning() method.
$this->log(Logger::WARNING, $message, $context); /**
} * @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function notice($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement notice() method.
public function notice($message, array $context = []) $this->log(Logger::NOTICE, $message, $context);
{ }
// TODO: Implement notice() method.
$this->log(Logger::NOTICE, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function info($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement info() method.
public function info($message, array $context = []) $this->log(Logger::INFO, $message, $context);
{ }
// TODO: Implement info() method.
$this->log(Logger::INFO, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function debug($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement debug() method.
public function debug($message, array $context = []) $this->log(Logger::DEBUG, $message, $context);
{ }
// TODO: Implement debug() method.
$this->log(Logger::DEBUG, $message, $context);
} /**
* @param mixed $level
* @param string $message
/** * @param array $context
* @param mixed $level * @throws ConfigException
* @param string $message */
* @param array $context public function log($level, $message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement log() method.
public function log($level, $message, array $context = []) $levels = Config::get('log.level', Logger::LOGGER_LEVELS);
{ if (!in_array($level, $levels) || str_contains($message, 'Event::rshutdown')) {
// TODO: Implement log() method. return;
$levels = Config::get('log.level', Logger::LOGGER_LEVELS); }
if (!in_array($level, $levels)) {
return; $_string = '[' . now() . '] production.' . $level . ': ' . $this->_string($message, $context);
}
file_put_contents('php://output', $_string);
$_string = '[' . now() . '] production.' . $level . ': ' . $this->_string($message, $context);
$this->_loggers[] = $_string;
file_put_contents('php://output', $_string); }
$this->_loggers[] = $_string;
} /**
* @param OnWorkerStop $param
* @throws Exception
/** */
* @param OnWorkerStop $param public function onAfterRequest(OnWorkerStop $param)
* @throws Exception {
*/ $loggers = implode(PHP_EOL, $this->_loggers);
public function onAfterRequest(OnWorkerStop $param) $this->_loggers = [];
{ if (!empty($loggers)) {
$loggers = implode(PHP_EOL, $this->_loggers); $filename = storage('log-' . date('Y-m-d') . '.log', 'log/');
$this->_loggers = [];
if (!empty($loggers)) { file_put_contents($filename, $loggers);
$filename = storage('log-' . date('Y-m-d') . '.log', 'logs/'); }
}
file_put_contents($filename, $loggers);
}
} /**
* @return void
* @throws Exception
/** */
* @param $message public function flush()
* @param $context {
* @return string $this->removeFile(storage());
*/ }
private function _string($message, $context): string
{
if (!empty($context)) { /**
return $message . ' ' . print_r($context, true) . PHP_EOL; * @param string $dirname
} * @return void
return $message . PHP_EOL; */
} private function removeFile(string $dirname)
} {
$paths = new DirectoryIterator($dirname);
/** @var DirectoryIterator $path */
foreach ($paths as $path) {
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
continue;
}
if ($path->isDir()) {
$directory = rtrim($path->getRealPath(), '/');
$this->removeFile($directory);
}
@unlink($path->getRealPath());
}
}
/**
* @param $message
* @param $context
* @return string
*/
private function _string($message, $context): string
{
if (!empty($context)) {
return $message . ' ' . PHP_EOL . print_r($context, true) . PHP_EOL;
}
return $message . PHP_EOL;
}
}
+14 -14
View File
@@ -1,14 +1,14 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Kiri\Application; use Kiri\Application;
interface Provider interface Provider
{ {
public function onImport(Application $application); public function onImport(Application $application);
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
/** /**
* Class Providers * Class Providers
* @package Kiri\Abstracts * @package Kiri\Abstracts
*/ */
abstract class Providers extends Component implements Provider abstract class Providers extends Component implements Provider
{ {
} }
+32 -37
View File
@@ -1,37 +1,32 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Annotation\Annotation as SAnnotation; use Kiri\Annotation\Annotation as SAnnotation;
use Database\Connection; use Database\Connection;
use Database\DatabasesProviders; use Database\DatabasesProviders;
use Http\Handler\Client\Client; use Kiri\Message\Handler\Router;
use Http\Handler\Client\Curl; use Kiri\Server\Server;
use Http\Handler\Router; use Kiri\Async;
use Server\Server; use Kiri\Error\Logger;
use Kiri\Crontab\Producer; use Kiri\Jwt\JWTAuth;
use Kiri\Async;
use Kiri\Error\Logger; /**
use Kiri\Jwt\JWTAuth; * Trait TraitApplication
* @package Kiri\Abstracts
/** * @property Router $router
* Trait TraitApplication * @property Server $server
* @package Kiri\Abstracts * @property DatabasesProviders $db
* @property Router $router * @property Async $async
* @property Server $server * @property Logger $logger
* @property DatabasesProviders $db * @property JWTAuth $jwt
* @property Async $async * @property SAnnotation $annotation
* @property Logger $logger * @property BaseGoto $goto
* @property JWTAuth $jwt * @property Connection $databases
* @property SAnnotation $annotation */
* @property BaseGoto $goto trait TraitApplication
* @property Client $client {
* @property Connection $databases
* @property Curl $curl }
*/
trait TraitApplication
{
}
+260 -256
View File
@@ -1,256 +1,260 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/25 0025 * Date: 2018/4/25 0025
* Time: 18:38 * Time: 18:38
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri; namespace Kiri;
use Closure; use Closure;
use Database\DatabasesProviders; use Database\DatabasesProviders;
use Exception; use Exception;
use Kiri\Abstracts\BaseApplication; use Kiri;
use Kiri\Abstracts\Config; use Kiri\Abstracts\{BaseApplication, Config, Kernel};
use Kiri\Abstracts\Kernel; use Kiri\Crontab\CrontabProviders;
use Kiri\Crontab\CrontabProviders; use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute};
use Kiri\Events\OnAfterCommandExecute; use Kiri\FileListen\HotReload;
use Kiri\Events\OnBeforeCommandExecute; use Kiri\Server\ServerProviders;
use Kiri\Exception\NotFindClassException; use ReflectionException;
use Kiri\FileListen\HotReload; use stdClass;
use ReflectionException; use Swoole\Process;
use Server\ServerProviders; use Swoole\Timer;
use stdClass; use Symfony\Component\Console\{Application as ConsoleApplication,
use Swoole\Process; Command\Command,
use Swoole\Timer; Input\ArgvInput,
use Symfony\Component\Console\Application as ConsoleApplication; Output\ConsoleOutput,
use Symfony\Component\Console\Command\Command; Output\OutputInterface
use Symfony\Component\Console\Input\ArgvInput; };
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
/**
/** * Class Init
* Class Init *
* * @package Kiri
* @package Kiri *
* * @property-read Config $config
* @property-read Config $config */
*/ class Application extends BaseApplication
class Application extends BaseApplication {
{
/**
/** * @var string
* @var string */
*/ public string $id = 'uniqueId';
public string $id = 'uniqueId';
public string $state = '';
public string $state = '';
/** @var array<array<Process>> */
/** @var array<array<Process>> */ private array $_process = [];
private array $_process = [];
/**
/** */
*/ public function init()
public function init() {
{ $this->import(ServerProviders::class);
$this->import(ServerProviders::class);
$this->register(Runtime::class);
$this->register(Runtime::class); }
}
/**
/** * @throws
* @throws */
*/ public function withDatabase()
public function withDatabase() {
{ $this->import(DatabasesProviders::class);
$this->import(DatabasesProviders::class); }
}
/**
/** * @throws
* @throws */
*/ public function withCrontab()
public function withCrontab() {
{ $this->import(CrontabProviders::class);
$this->import(CrontabProviders::class); }
}
/**
/** * @param string $class
* @param string $class * @param Process $process
* @param Process $process */
*/ public function addProcess(string $class, Process $process)
public function addProcess(string $class, Process $process) {
{ }
}
/**
/** * @return Process[]
* @return Process[] */
*/ public function getProcess(): array
public function getProcess(): array {
{ return $this->_process;
return $this->_process; }
}
/**
/** * @param string $class
* @param string $class * @return Process|null
* @return Process|null */
*/ public function getProcessName(string $class): ?Process
public function getProcessName(string $class): ?Process {
{ return $this->_process[$class] ?? null;
return $this->_process[$class] ?? null; }
}
/**
/** * @throws
* @throws */
*/ public function withFileChangeListen()
public function withFileChangeListen() {
{ $container = Kiri::getDi();
$container = Kiri::getDi();
$console = $container->get(ConsoleApplication::class);
$console = $container->get(ConsoleApplication::class); $console->add($container->get(HotReload::class));
$console->add($container->get(HotReload::class)); }
}
/**
/** * @param Closure|array $closure
* @param Closure|array $closure * @return $this
* @return $this * @throws Exception
* @throws Exception */
*/ public function middleware(Closure|array $closure): static
public function middleware(Closure|array $closure): static {
{ return $this;
return $this; }
}
/**
/** * @param bool $useTree
* @param bool $useTree * @return $this
* @return $this * @throws Exception
* @throws Exception */
*/ public function setUseTree(bool $useTree): static
public function setUseTree(bool $useTree): static {
{ return $this;
return $this; }
}
/**
/** * @param string $service
* @param string $service * @return $this
* @return $this * @throws
* @throws */
*/ public function import(string $service): static
public function import(string $service): static {
{ if (!class_exists($service)) {
if (!class_exists($service)) { return $this;
return $this; }
} $class = Kiri::getDi()->get($service);
$class = Kiri::getDi()->get($service); if (method_exists($class, 'onImport')) {
if (method_exists($class, 'onImport')) { $class->onImport($this);
$class->onImport($this); }
} return $this;
return $this; }
}
/**
/** * @param Kernel $kernel
* @param Kernel $kernel * @return $this
* @return $this */
*/ public function commands(Kernel $kernel): static
public function commands(Kernel $kernel): static {
{ foreach ($kernel->getCommands() as $command) {
foreach ($kernel->getCommands() as $command) { $this->register($command);
$this->register($command); }
} return $this;
return $this; }
}
/**
/** * @param string $command
* @param string $command * @throws
* @throws */
*/ public function register(string $command)
public function register(string $command) {
{ di(ConsoleApplication::class)->add(di($command));
di(ConsoleApplication::class)->add(di($command)); }
}
/**
/** * @param array $argv
* @param array $argv * @return void
* @return void */
*/ public function execute(array $argv): void
public function execute(array $argv): void {
{ ini_set('swoole.enable_preemptive_scheduler', 'On');
/** @var InputInterface $input */ ini_set('swoole.enable_library', 'On');
[$input, $output] = $this->argument($argv); [$input, $output] = $this->argument($argv);
try { try {
$console = di(ConsoleApplication::class); $console = di(ConsoleApplication::class);
$command = $input->getFirstArgument(); $command = $input->getFirstArgument();
if (empty($command)) { if (empty($command)) {
$command = 'sw:server'; $command = 'sw:server';
} }
$command = $console->find($command); $command = $console->find($command);
if ($command instanceof Command) { if ($command instanceof Command) {
$this->enableFileChange($command, $input, $output); $this->enableFileChange($command, $input, $output);
} }
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
$output->writeln(jTraceEx($exception)); $output->writeln(jTraceEx($exception));
} finally { } finally {
Timer::clearAll(); Timer::clearAll();
} }
} }
/**
/** * @param $argv
* @param $argv * @return array
* @return array */
*/ private function argument($argv): array
private function argument($argv): array {
{ return [new ArgvInput($argv), new ConsoleOutput()];
return [new ArgvInput($argv), new ConsoleOutput()]; }
}
/**
* @throws ReflectionException
/** * @throws Exception
* @throws NotFindClassException */
* @throws ReflectionException private function enableFileChange(Command $class, $input, $output): void
* @throws Exception {
*/ fire(new OnBeforeCommandExecute());
private function enableFileChange(Command $class, $input, $output): void if (!($class instanceof HotReload)) {
{ $config = Config::get('scanner', []);
fire(new OnBeforeCommandExecute()); if (!empty($config)) {
if (!($class instanceof HotReload)) { foreach ($config as $key => $value) {
scan_directory(directory('app'), 'App'); scan_directory($value, $key);
} }
$class->run($input, $output); }
fire(new OnAfterCommandExecute()); scan_directory(MODEL_PATH, 'app\Model');
$output->writeln('ok' . PHP_EOL); }
}
$this->getContainer()->setBindings(OutputInterface::class, $output);
$class->run($input, $output);
fire(new OnAfterCommandExecute());
/** $output->writeln('ok' . PHP_EOL);
* @param $className }
* @param null $abstracts
* @return stdClass
* @throws Exception /**
*/ * @param $className
public function make($className, $abstracts = null): stdClass * @param null $abstracts
{ * @return stdClass
return make($className, $abstracts); * @throws Exception
} */
} public function make($className, $abstracts = null): stdClass
{
return make($className, $abstracts);
}
}
+44 -43
View File
@@ -1,43 +1,44 @@
<?php <?php
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Server\ServerManager; use Kiri\Server\ServerManager;
use Kiri\Task\AsyncTaskExecute;
/** use Kiri;
* Class Async /**
* @package Kiri * Class Async
*/ * @package Kiri
class Async extends Component */
{ class Async extends Component
{
private static array $_absences = [];
private static array $_absences = [];
/**
* @param string $name /**
* @param string $handler * @param string $name
*/ * @param string $handler
public function addAsync(string $name, string $handler) */
{ public function addAsync(string $name, string $handler)
static::$_absences[$name] = $handler; {
} static::$_absences[$name] = $handler;
}
/**
* @param string $name /**
* @param array $params * @param string $name
* @throws Exception * @param array $params
*/ * @throws Exception
public function dispatch(string $name, array $params = []) */
{ public function dispatch(string $name, array $params = [])
$context = di(ServerManager::class); {
$context->task(static::$_absences[$name], $params); $context = di(AsyncTaskExecute::class);
} $context->execute(static::$_absences[$name], $params);
}
}
}
+185 -152
View File
@@ -1,152 +1,185 @@
<?php <?php
namespace Kiri\Cache\Base; namespace Kiri\Cache\Base;
use Kiri\Abstracts\Logger; use Exception;
use Kiri\Exception\RedisConnectException; use Kiri\Abstracts\Logger;
use Kiri\Kiri; use Kiri\Events\EventProvider;
use Kiri\Pool\StopHeartbeatCheck; use Kiri\Exception\RedisConnectException;
use RedisException; use Kiri;
use Kiri\Context; use Kiri\Pool\StopHeartbeatCheck;
use Swoole\Timer; use Kiri\Server\Events\OnWorkerExit;
use RedisException;
use Swoole\Timer;
/**
*
*/ /**
class Redis implements StopHeartbeatCheck *
{ */
class Redis implements StopHeartbeatCheck
const DB_ERROR_MESSAGE = 'The system is busy, please try again later.'; {
const DB_ERROR_MESSAGE = 'The system is busy, please try again later.';
private ?\Redis $pdo = null;
private ?\Redis $pdo = null;
private int $_transaction = 0;
public string $host;
private int $_timer = -1; public int $port;
private int $_last = 0; public int $database = 0;
public string $auth = '';
/**
* @param string $host public string $prefix = '';
* @param int $port
* @param int $database public int $timeout = 30;
* @param string $auth
* @param string $prefix public int $read_timeout = 30;
* @param int $timeout
* @param int $read_timeout public array $pool = [];
*/
public function __construct(public string $host, public int $port, public int $database = 0, private int $_timer = -1;
public string $auth = '', public string $prefix = '', public int $timeout = 30,
public int $read_timeout = 30) private int $_last = 0;
{
}
/**
public function init() * @param array $config
{ */
$this->heartbeat_check(); public function __construct(array $config)
} {
$this->host = $config['host'];
$this->port = $config['port'];
/** $this->database = $config['databases'];
* $this->auth = $config['auth'];
*/ $this->prefix = $config['prefix'];
public function heartbeat_check(): void $this->timeout = $config['timeout'];
{ $this->read_timeout = $config['read_timeout'];
if (env('state', 'start') == 'exit') { $this->pool = $config['pool'];
return; }
}
if ($this->_timer === -1 && Context::inCoroutine()) {
$this->_timer = Timer::tick(1000, function () { public function init()
try { {
if (env('state', 'start') == 'exit') { $this->heartbeat_check();
Kiri::getDi()->get(Logger::class)->critical('timer end'); }
$this->stopHeartbeatCheck();
}
if (time() - $this->_last > 10 * 60) {
$this->stopHeartbeatCheck();
$this->pdo = null; /**
} * @param Kiri\Server\Events\OnWorkerExit $exit
} catch (\Throwable $throwable) { * @return void
error($throwable); */
} public function onWorkerExit(OnWorkerExit $exit)
}); {
} $this->stopHeartbeatCheck();
} }
/** /**
* *
*/ */
public function stopHeartbeatCheck(): void public function heartbeat_check(): void
{ {
if ($this->_timer > -1) {
Timer::clear($this->_timer); if ($this->_timer === -1) {
} $this->_timer = Timer::tick(1000, fn() => $this->waite());
$this->_timer = -1; }
} }
/** /**
* @param string $name * @throws Exception
* @param array $arguments */
* @return mixed private function waite(): void
* @throws RedisConnectException|RedisException {
*/ try {
public function __call(string $name, array $arguments) if ($this->_timer === -1) {
{ Kiri::getDi()->get(Logger::class)->critical('timer end');
if (!method_exists($this, $name)) { $this->stopHeartbeatCheck();
return $this->_pdo()->{$name}(...$arguments); }
} if (time() - $this->_last > intval($this->pool['tick'] ?? 60)) {
return $this->{$name}(...$arguments); $this->stopHeartbeatCheck();
}
$this->pdo = null;
}
/** } catch (\Throwable $throwable) {
* @return \Redis error($throwable);
* @throws RedisConnectException }
* @throws RedisException }
*/
public function _pdo(): \Redis
{ /**
if ($this->_timer === -1) { *
$this->heartbeat_check(); */
} public function stopHeartbeatCheck(): void
if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) { {
$this->pdo = $this->newClient(); if ($this->_timer > -1) {
} Timer::clear($this->_timer);
return $this->pdo; }
} $this->_timer = -1;
}
/**
* @return \Redis /**
* @throws RedisConnectException * @param string $name
*/ * @param array $arguments
private function newClient(): \Redis * @return mixed
{ * @throws RedisConnectException|RedisException
$redis = new \Redis(); */
if (!$redis->connect($this->host, $this->port, $this->timeout)) { public function __call(string $name, array $arguments)
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port)); {
} if (!method_exists($this, $name)) {
if (!empty($this->auth) && !$redis->auth($this->auth)) { return $this->_pdo()->{$name}(...$arguments);
throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth)); }
} return $this->{$name}(...$arguments);
if ($this->read_timeout < 0) { }
$this->read_timeout = 0;
}
$redis->select($this->database); /**
if ($this->read_timeout > 0) { * @return \Redis
$redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout); * @throws RedisConnectException
} * @throws RedisException
$redis->setOption(\Redis::OPT_PREFIX, $this->prefix); */
return $redis; public function _pdo(): \Redis
{
} if ($this->_timer === -1) {
$this->heartbeat_check();
} }
if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) {
$this->pdo = $this->newClient();
}
return $this->pdo;
}
/**
* @return \Redis
* @throws RedisConnectException
*/
private function newClient(): \Redis
{
$redis = new \Redis();
if (!$redis->connect($this->host, $this->port, $this->timeout)) {
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port));
}
if (!empty($this->auth) && !$redis->auth($this->auth)) {
throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth));
}
if ($this->read_timeout < 0) {
$this->read_timeout = 0;
}
$redis->select($this->database);
if ($this->read_timeout > 0) {
$redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
}
$redis->setOption(\Redis::OPT_PREFIX, $this->prefix);
return $redis;
}
}
+141 -141
View File
@@ -1,141 +1,141 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/5/2 0002 * Date: 2018/5/2 0002
* Time: 14:51 * Time: 14:51
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Cache;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Swoole\Coroutine\System; use Swoole\Coroutine\System;
/** /**
* Class File * Class File
* @package Kiri\Kiri\Cache * @package Kiri\Cache
*/ */
class File extends Component implements ICache class File extends Component implements ICache
{ {
public string $path; public string $path;
/** /**
* @param $key * @param $key
* @param $val * @param $val
* @return string|int * @return string|int
*/ */
public function set($key, $val): string|int public function set($key, $val): string|int
{ {
if (is_array($val) || is_object($val)) { if (is_array($val) || is_object($val)) {
$val = swoole_serialize($val); $val = swoole_serialize($val);
} }
$tmpFile = $this->getCacheKey($key); $tmpFile = $this->getCacheKey($key);
if (!$this->exists($tmpFile)) { if (!$this->exists($tmpFile)) {
touch($tmpFile); touch($tmpFile);
} }
return System::writeFile($tmpFile, $val, LOCK_EX); return System::writeFile($tmpFile, $val, LOCK_EX);
} }
/** /**
* @param $key * @param $key
* @param array $hashKeys * @param array $hashKeys
* @return array|bool * @return array|bool
*/ */
public function hMGet($key, array $hashKeys): array|bool public function hMGet($key, array $hashKeys): array|bool
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
$nowHash = []; $nowHash = [];
foreach ($hashKeys as $hashKey) { foreach ($hashKeys as $hashKey) {
$nowHash[$hashKey] = $hash[$hashKey] ?? null; $nowHash[$hashKey] = $hash[$hashKey] ?? null;
} }
return $nowHash; return $nowHash;
} }
/** /**
* @param $key * @param $key
* @param array $val * @param array $val
* @return bool|int|string * @return bool|int|string
*/ */
public function hMSet($key, array $val): bool|int|string public function hMSet($key, array $val): bool|int|string
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
$merge = array_merge($hash, $val); $merge = array_merge($hash, $val);
return $this->set($key, $merge); return $this->set($key, $merge);
} }
/** /**
* @param string $key * @param string $key
* @param string $hashKey * @param string $hashKey
* @return string|int|bool * @return string|int|bool
*/ */
public function hGet(string $key, string $hashKey): string|int|bool public function hGet(string $key, string $hashKey): string|int|bool
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
return $hash[$hashKey] ?? false; return $hash[$hashKey] ?? false;
} }
/** /**
* @param $key * @param $key
* @param $hashKey * @param $hashKey
* @param $hashValue * @param $hashValue
* @return bool|int|string * @return bool|int|string
*/ */
public function hSet($key, $hashKey, $hashValue): bool|int|string public function hSet($key, $hashKey, $hashValue): bool|int|string
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
$hash[$hashKey] = $hashValue; $hash[$hashKey] = $hashValue;
return $this->set($key, $hash); return $this->set($key, $hash);
} }
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
#[Pure] public function exists($key): bool #[Pure] public function exists($key): bool
{ {
return file_exists($key); return file_exists($key);
} }
/** /**
* @param $key * @param $key
* @return mixed|bool * @return mixed|bool
*/ */
public function get($key): string|bool public function get($key): string|bool
{ {
$tmpFile = $this->getCacheKey($key); $tmpFile = $this->getCacheKey($key);
if (!$this->exists($tmpFile)) { if (!$this->exists($tmpFile)) {
return false; return false;
} }
$content = file_get_contents($tmpFile); $content = file_get_contents($tmpFile);
return swoole_unserialize($content); return swoole_unserialize($content);
} }
/** /**
* @param $key * @param $key
* @return string * @return string
* @throws * @throws
*/ */
private function getCacheKey($key): string private function getCacheKey($key): string
{ {
return storage($key, 'cache'); return storage($key, 'cache');
} }
} }
+65 -65
View File
@@ -1,65 +1,65 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/11/8 0008 * Date: 2018/11/8 0008
* Time: 16:35 * Time: 16:35
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Cache;
/** /**
* Interface ICache * Interface ICache
* @package Kiri\Kiri\Cache * @package Kiri\Cache
*/ */
interface ICache interface ICache
{ {
/** /**
* @param $key * @param $key
* @param $val * @param $val
* @return string|int * @return string|int
*/ */
public function set($key, $val): string|int; public function set($key, $val): string|int;
/** /**
* @param $key * @param $key
* @return string|int|bool * @return string|int|bool
*/ */
public function get($key): string|int|bool; public function get($key): string|int|bool;
/** /**
* @param $key * @param $key
* @param array $hashKeys * @param array $hashKeys
* @return array|bool|null * @return array|bool|null
*/ */
public function hMGet($key, array $hashKeys): array|bool|null; public function hMGet($key, array $hashKeys): array|bool|null;
/** /**
* @param $key * @param $key
* @param array $val * @param array $val
* @return mixed * @return mixed
*/ */
public function hMSet($key, array $val): mixed; public function hMSet($key, array $val): mixed;
/** /**
* @param string $key * @param string $key
* @param string $hashKey * @param string $hashKey
* @return string|int|bool * @return string|int|bool
*/ */
public function hGet(string $key, string $hashKey): string|int|bool; public function hGet(string $key, string $hashKey): string|int|bool;
/** /**
* @param $key * @param $key
* @param $hashKey * @param $hashKey
* @param $hashValue * @param $hashValue
* @return mixed * @return mixed
*/ */
public function hSet($key, $hashKey, $hashValue): mixed; public function hSet($key, $hashKey, $hashValue): mixed;
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
public function exists($key): bool; public function exists($key): bool;
} }
+191 -160
View File
@@ -1,160 +1,191 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/27 0027 * Date: 2018/4/27 0027
* Time: 11:00 * Time: 11:00
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Cache;
use Annotation\Inject; use Exception;
use Exception; use Kiri\Abstracts\Component;
use Server\Events\OnWorkerExit; use Kiri\Abstracts\Config;
use Kiri\Abstracts\Component; use Kiri\Core\Json;
use Kiri\Abstracts\Config; use Kiri\Events\EventProvider;
use Kiri\Core\Json; use Kiri\Exception\ConfigException;
use Kiri\Events\EventProvider; use Kiri;
use Kiri\Exception\ConfigException; use Kiri\Pool\Redis as PoolRedis;
use Kiri\Kiri; use Kiri\Annotation\Inject;
use Kiri\Pool\Redis as PoolRedis; use Kiri\Server\Events\OnWorkerExit;
use Psr\Container\ContainerExceptionInterface;
/** use Psr\Container\NotFoundExceptionInterface;
* Class Redis use Swoole\Timer;
* @package Kiri\Kiri\Cache
* @mixin \Redis /**
*/ * Class Redis
class Redis extends Component * @package Kiri\Cache
{ * @mixin \Redis
*/
/** class Redis extends Component
* @var EventProvider {
*/
#[Inject(EventProvider::class)]
public EventProvider $eventProvider; const REDIS_OPTION_HOST = 'host';
const REDIS_OPTION_PORT = 'port';
const REDIS_OPTION_PREFIX = 'prefix';
/** const REDIS_OPTION_AUTH = 'auth';
* @throws ConfigException const REDIS_OPTION_DATABASES = 'databases';
* @throws Exception const REDIS_OPTION_TIMEOUT = 'timeout';
*/ const REDIS_OPTION_POOL = 'pool';
public function init() const REDIS_OPTION_POOL_TICK = 'tick';
{ const REDIS_OPTION_POOL_MIN = 'min';
$connections = Kiri::getDi()->get(PoolRedis::class); const REDIS_OPTION_POOL_MAX = 'max';
$config = $this->get_config();
/**
$length = Config::get('connections.pool.max', 10); * @return void
* @throws ConfigException
$this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0); * @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
$connections->initConnections('Redis:' . $config['host'], true, $length); * @throws Exception
} */
public function init()
{
/** $connections = Kiri::getDi()->get(PoolRedis::class);
* @param $name
* @param $arguments $config = $this->get_config();
* @return mixed
* @throws $length = Config::get('cache.redis.pool.max', 10);
*/
public function __call($name, $arguments): mixed $this->getEventProvider()->on(OnWorkerExit::class, [$this, 'destroy'], 0);
{
$time = microtime(true); $connections->initConnections('Redis:' . $config['host'], true, $length);
if (method_exists($this, $name)) { }
$data = $this->{$name}(...$arguments);
} else {
$data = $this->proxy($name, $arguments); /**
} * @param $name
if (microtime(true) - $time >= 0.02) { * @param $arguments
$this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time)); * @return mixed
} * @throws
return $data; */
} public function __call($name, $arguments): mixed
{
$time = microtime(true);
/** if (method_exists($this, $name)) {
* @param $key $data = $this->{$name}(...$arguments);
* @param int $timeout } else {
* @return bool|int $data = $this->proxy($name, $arguments);
* @throws Exception }
*/ if (microtime(true) - $time >= 0.02) {
public function lock($key, int $timeout = 5): bool|int $this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time));
{ }
$script = <<<SCRIPT return $data;
local _nx = redis.call('setnx',KEYS[1], ARGV[1]) }
if (_nx ~= 0) then
redis.call('expire',KEYS[1], ARGV[1])
return 1 /**
end * @param $key
return 0 * @param int $timeout
SCRIPT; * @return bool
return $this->eval($script, ['{lock}:' . $key, $timeout], 1); */
} public function waite($key, int $timeout = 5): bool
{
$time = time();
/** while (!$this->setNx($key, 1)) {
* @param $key if (time()- $time >= $timeout) {
* @return int return FALSE;
* @throws Exception }
*/ usleep(1000);
public function unlock($key): int }
{ $this->expire($key, $timeout);
return $this->del('{lock}:' . $key); return TRUE;
} }
/** /**
* @throws ConfigException * @param $key
* @throws Exception * @param int $timeout
*/ * @return bool|int
public function release() * @throws Exception
{ */
$connections = Kiri::getDi()->get(PoolRedis::class); public function lock($key, int $timeout = 5): bool|int
$connections->release($this->get_config(), true); {
} $script = <<<SCRIPT
local _nx = redis.call('setnx',KEYS[1], ARGV[1])
/** if (_nx ~= 0) then
* 销毁连接池 redis.call('expire',KEYS[1], ARGV[1])
* @throws ConfigException return 1
* @throws Exception end
*/ return 0
public function destroy() SCRIPT;
{ return $this->eval($script, ['{lock}:' . $key, $timeout], 1);
$connections = Kiri::getDi()->get(PoolRedis::class); }
$connections->connection_clear($this->get_config(), true);
}
/**
/** * @param $key
* @param $name * @return int
* @param $arguments * @throws Exception
* @return mixed */
* @throws ConfigException public function unlock($key): int
* @throws Exception {
*/ return $this->del('{lock}:' . $key);
public function proxy($name, $arguments): mixed }
{
$connections = Kiri::getDi()->get(PoolRedis::class);
/**
$config = $this->get_config(); * @throws ConfigException
* @throws Exception
$client = $connections->get($config, true); */
if (!($client instanceof Base\Redis)) { public function release()
throw new Exception('Redis connections more.'); {
} $connections = Kiri::getDi()->get(PoolRedis::class);
$response = $client->{$name}(...$arguments); $connections->release($this->get_config(), true);
$this->release(); }
return $response;
} /**
* 销毁连接池
/** * @throws ConfigException
* @return array * @throws Exception
* @throws ConfigException */
*/ public function destroy()
public function get_config(): array {
{ $connections = Kiri::getDi()->get(PoolRedis::class);
return Config::get('cache.redis', null, true); $connections->connection_clear($this->get_config(), true);
} }
} /**
* @param $name
* @param $arguments
* @return mixed
* @throws ConfigException
* @throws Exception
*/
public function proxy($name, $arguments): mixed
{
$connections = Kiri::getDi()->get(PoolRedis::class);
$config = $this->get_config();
$client = $connections->get($config, true);
if (!($client instanceof Base\Redis)) {
throw new Exception('Redis connections more.');
}
$response = $client->{$name}(...$arguments);
$this->release();
return $response;
}
/**
* @return array
* @throws ConfigException
*/
public function get_config(): array
{
return Config::get('cache.redis', null, true);
}
}
+209 -189
View File
@@ -1,189 +1,209 @@
<?php <?php
namespace Kiri; namespace Kiri;
use Kiri\Abstracts\BaseContext; use Kiri\Abstracts\BaseContext;
use Swoole\Coroutine; use Swoole\Coroutine;
use Kiri;
/** /**
* Class Context * Class Context
* @package Yoc\http * @package Yoc\http
*/ */
class Context extends BaseContext class Context extends BaseContext
{ {
protected static array $_contents = []; protected static array $_contents = [];
/** /**
* @param $id * @param $id
* @param $context * @param $context
* @param null $coroutineId * @param null $coroutineId
* @return mixed * @return mixed
*/ */
public static function setContext($id, $context, $coroutineId = null): mixed public static function setContext($id, $context, $coroutineId = null): mixed
{ {
if (Coroutine::getCid() === -1) { if (is_null($coroutineId)) {
return static::$_contents[$id] = $context; $coroutineId = Coroutine::getCid();
} }
return Coroutine::getContext($coroutineId)[$id] = $context; if (Coroutine::getCid() !== -1) {
} return Coroutine::getContext($coroutineId)[$id] = $context;
}
/** return static::$_contents[$id] = $context;
* @param $id }
* @param int $value
* @param null $coroutineId /**
* @return bool|int * @param $id
*/ * @param int $value
public static function increment($id, int $value = 1, $coroutineId = null): bool|int * @param null $coroutineId
{ * @return bool|int
if (!isset(Coroutine::getContext($coroutineId)[$id])) { */
Coroutine::getContext($coroutineId)[$id] = 0; public static function increment($id, int $value = 1, $coroutineId = null): bool|int
} {
return Coroutine::getContext($coroutineId)[$id] += $value; if (is_null($coroutineId)) {
} $coroutineId = Coroutine::getCid();
}
/** if (!isset(Coroutine::getContext($coroutineId)[$id])) {
* @param $id Coroutine::getContext($coroutineId)[$id] = 0;
* @param int $value }
* @param null $coroutineId return Coroutine::getContext($coroutineId)[$id] += $value;
* @return bool|int }
*/
public static function decrement($id, int $value = 1, $coroutineId = null): bool|int /**
{ * @param $id
if (!isset(Coroutine::getContext($coroutineId)[$id])) { * @param int $value
Coroutine::getContext($coroutineId)[$id] = 0; * @param null $coroutineId
} * @return bool|int
return Coroutine::getContext($coroutineId)[$id] -= $value; */
} public static function decrement($id, int $value = 1, $coroutineId = null): bool|int
{
/** if (is_null($coroutineId)) {
* @param $id $coroutineId = Coroutine::getCid();
* @param null $default }
* @param null $coroutineId if (!isset(Coroutine::getContext($coroutineId)[$id])) {
* @return mixed Coroutine::getContext($coroutineId)[$id] = 0;
*/ }
public static function getContext($id, $default = null, $coroutineId = null): mixed return Coroutine::getContext($coroutineId)[$id] -= $value;
{ }
if (Coroutine::getCid() === -1) {
return static::loadByStatic($id, $default); /**
} * @param $id
return static::loadByContext($id, $default, $coroutineId); * @param null $default
} * @param null $coroutineId
* @return mixed
*/
/** public static function getContext($id, $default = null, $coroutineId = null): mixed
* @param $id {
* @param null $default if (Coroutine::getCid() === -1) {
* @param null $coroutineId return static::loadByStatic($id, $default);
* @return mixed }
*/ return static::loadByContext($id, $default, $coroutineId);
private static function loadByContext($id, $default = null, $coroutineId = null): mixed }
{
return Coroutine::getContext($coroutineId)[$id] ?? $default;
} /**
* @param $id
* @param null $default
/** * @param null $coroutineId
* @param $id * @return mixed
* @param null $default */
* @return mixed private static function loadByContext($id, $default = null, $coroutineId = null): mixed
*/ {
private static function loadByStatic($id, $default = null): mixed if (is_null($coroutineId)) {
{ $coroutineId = Coroutine::getCid();
return static::$_contents[$id] ?? $default; }
} return Coroutine::getContext($coroutineId)[$id] ?? $default;
}
/**
* @param null $coroutineId /**
* @return mixed * @param $id
*/ * @param null $default
public static function getAllContext($coroutineId = null): mixed * @return mixed
{ */
if (Coroutine::getCid() === -1) { private static function loadByStatic($id, $default = null): mixed
return Coroutine::getContext($coroutineId) ?? []; {
} else { return static::$_contents[$id] ?? $default;
return static::$_contents ?? []; }
}
}
/**
/** * @param null $coroutineId
* @param string $id * @return mixed
* @param null $coroutineId */
*/ public static function getAllContext($coroutineId = null): mixed
public static function remove(string $id, $coroutineId = null) {
{ if (Coroutine::getCid() === -1) {
if (!static::hasContext($id, $coroutineId)) { return Coroutine::getContext($coroutineId) ?? [];
return; } else {
} return static::$_contents ?? [];
if (Coroutine::getCid() === -1) { }
unset(static::$_contents[$id]); }
} else {
unset(Coroutine::getContext($coroutineId)[$id]); /**
} * @param string $id
} * @param null $coroutineId
*/
/** public static function remove(string $id, $coroutineId = null)
* @param $id {
* @param null $key if (is_null($coroutineId)) {
* @param null $coroutineId $coroutineId = Coroutine::getCid();
* @return bool }
*/ if (!static::hasContext($id, $coroutineId)) {
public static function hasContext($id, $key = null, $coroutineId = null): bool return;
{ }
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
return static::searchByStatic($id, $key); unset(static::$_contents[$id]);
} } else {
return static::searchByCoroutine($id, $key, $coroutineId); unset(Coroutine::getContext($coroutineId)[$id]);
} }
}
/** /**
* @param $id * @param $id
* @param null $key * @param null $key
* @return bool * @param null $coroutineId
*/ * @return bool
private static function searchByStatic($id, $key = null): bool */
{ public static function hasContext($id, $key = null, $coroutineId = null): bool
if (!isset(static::$_contents[$id])) { {
return false; if (Coroutine::getCid() === -1) {
} return static::searchByStatic($id, $key);
if (!empty($key) && !isset(static::$_contents[$id][$key])) { }
return false; return static::searchByCoroutine($id, $key, $coroutineId);
} }
return true;
}
/**
* @param $id
/** * @param null $key
* @param $id * @return bool
* @param null $key */
* @param null $coroutineId private static function searchByStatic($id, $key = null): bool
* @return bool {
*/ if (!isset(static::$_contents[$id])) {
private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool return false;
{ }
if (!isset(Coroutine::getContext($coroutineId)[$id])) { $value = static::$_contents[$id];
return false; if (!empty($key) && is_array($value)) {
} return isset($value[$key]);
if ($key !== null) { }
return isset((Coroutine::getContext($coroutineId)[$id] ?? [])[$key]); return true;
} }
return true;
}
/**
* @param $id
/** * @param null $key
* @return bool * @param null $coroutineId
*/ * @return bool
public static function inCoroutine(): bool */
{ private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool
return Coroutine::getCid() !== -1; {
} if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid();
} }
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
return false;
}
$value = Coroutine::getContext($coroutineId)[$id];
if ($key !== null && is_array($value)) {
return isset($value[$key]);
}
return true;
}
/**
* @return bool
*/
public static function inCoroutine(): bool
{
return Coroutine::getCid() !== -1;
}
}
+100 -100
View File
@@ -1,100 +1,100 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/4 0004 * Date: 2018/4/4 0004
* Time: 14:57 * Time: 14:57
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class ArrayAccess * Class ArrayAccess
* @package Kiri\Core * @package Kiri\Core
*/ */
class ArrayAccess class ArrayAccess
{ {
/** /**
* @param $data * @param $data
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function toArray($data): array public static function toArray($data): array
{ {
if (!is_object($data) && !is_array($data)) { if (!is_object($data) && !is_array($data)) {
return []; return [];
} }
if (is_object($data)) { if (is_object($data)) {
$data = self::objToArray($data); $data = self::objToArray($data);
} }
$tmp = []; $tmp = [];
if (!is_array($data)) { if (!is_array($data)) {
return $tmp; return $tmp;
} }
foreach ($data as $key => $val) { foreach ($data as $key => $val) {
if (is_array($val) || is_object($val)) { if (is_array($val) || is_object($val)) {
$tmp[$key] = self::toArray($val); $tmp[$key] = self::toArray($val);
} else { } else {
$tmp[$key] = $val; $tmp[$key] = $val;
} }
} }
return $tmp; return $tmp;
} }
/** /**
* @param $data * @param $data
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function objToArray($data): array public static function objToArray($data): array
{ {
if (!is_object($data)) { if (!is_object($data)) {
return $data; return $data;
} }
if (method_exists($data, 'get')) { if (method_exists($data, 'get')) {
$data = $data->get(); $data = $data->get();
if (is_array($data)) { if (is_array($data)) {
return $data; return $data;
} }
} }
if (method_exists($data, 'toArray')) { if (method_exists($data, 'toArray')) {
$data = $data->toArray(); $data = $data->toArray();
} else { } else {
$data = get_object_vars((object)$data); $data = get_object_vars((object)$data);
} }
return $data; return $data;
} }
/** /**
* @param array $oldArray * @param array $oldArray
* @param array $newArray * @param array $newArray
* @return array * @return array
*/ */
public static function merge(array $oldArray, array $newArray): array public static function merge(array $oldArray, array $newArray): array
{ {
if (empty($oldArray)) { if (empty($oldArray)) {
return $newArray; return $newArray;
} else if (empty($newArray)) { } else if (empty($newArray)) {
return $oldArray; return $oldArray;
} }
foreach ($newArray as $item => $value) { foreach ($newArray as $item => $value) {
if (!isset($oldArray[$item])) { if (!isset($oldArray[$item])) {
$oldArray[$item] = $value; $oldArray[$item] = $value;
} }
if (is_array($value)) { if (is_array($value)) {
$oldArray[$item] = self::merge($oldArray[$item], $value); $oldArray[$item] = self::merge($oldArray[$item], $value);
} else { } else {
$oldArray[$item] = $value; $oldArray[$item] = $value;
} }
} }
return $oldArray; return $oldArray;
} }
} }
+104 -106
View File
@@ -1,106 +1,104 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: dell * User: dell
* Date: 2019/1/14 0014 * Date: 2019/1/14 0014
* Time: 13:50 * Time: 13:50
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
/** /**
* Class DateFormat * Class DateFormat
* @package Kiri\Kiri\Core * @package Kiri\Core
*/ */
class DateFormat class DateFormat
{ {
/** /**
* @param $time * @param $time
* @return bool|false|int|string * @return bool|false|int|string
*/ */
private static function check($time): bool|int|string private static function check($time): bool|int|string
{ {
if ($time === null) { if ($time === null) {
$time = time(); $time = time();
} else if (is_numeric($time)) { } else if (is_numeric($time)) {
$length = strlen(floatval($time)); $length = strlen((string)$time);
if ($length != 10 && $length != 13) { if ($length != 10 && $length != 13) {
return false; return false;
} }
} else if (is_string($time)) { } else if (is_string($time)) {
$time = strtotime($time); $time = strtotime($time);
} }
if (date('Y-m-d', $time)) { if (date('Y-m-d', $time)) {
return $time; return $time;
} }
return false; return false;
} }
/** /**
* @param null $time * @param null $time
* @return bool|false|int * @return bool|false|int
* *
* 获取指定日期当周第一天的时间 * 获取指定日期当周第一天的时间
*/ */
public static function getWeekCurrentDay($time = null): bool|int public static function getWeekCurrentDay($time = null): bool|int
{ {
if (!($time = static::check($time))) { if (!($time = static::check($time))) {
return false; return false;
} }
$time = strtotime('-' . (date('N') - 1) . 'days', $time); $time = strtotime('-' . (date('N') - 1) . 'days', $time);
return strtotime(date('Y-m-d'), $time); return strtotime(date('Y-m-d'), $time);
} }
/** /**
* @param null $time * @param null $time
* @return bool|false|int * @return bool|false|int
* *
* 获取指定日期当月第一天的时间 * 获取指定日期当月第一天的时间
*/ */
public static function getMonthCurrentDay($time = null): bool|int public static function getMonthCurrentDay($time = null): bool|int
{ {
if (!($time = static::check($time))) { if (!($time = static::check($time))) {
return false; return false;
} }
return strtotime(date('Y-m', $time) . '-01'); return strtotime(date('Y-m', $time) . '-01');
} }
/** /**
* @param $time * @param $time
* @return bool|int|string 指定的月份有几天 * @return bool|int|string 指定的月份有几天
* 指定的月份有几天 * 指定的月份有几天
*/ */
public static function getMonthTotalDay($time): bool|int|string public static function getMonthTotalDay($time): bool|int|string
{ {
if (!($time = static::check($time))) { if (!($time = static::check($time))) {
return false; return false;
} }
$time = date('t', $time); return date('t', $time);
}
return $time;
} /**
* @param $startTime
/** * @param null $endTime
* @param $startTime * @return string
* @param null $endTime */
* @return string public static function mtime($startTime, $endTime = null)
*/ {
public static function mtime($startTime, $endTime = null) if ($endTime === null) {
{ $endTime = microtime(true);
if ($endTime === null) { }
$endTime = microtime(true); return sprintf('%.7f', $endTime - $startTime);
} }
return sprintf('%.7f', $endTime - $startTime); }
}
}
+58 -60
View File
@@ -1,60 +1,58 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Dtl * Class Dtl
* @package Kiri\Core * @package Kiri\Core
*/ */
class Dtl extends Component class Dtl extends Component
{ {
protected array $params; protected array $params;
/** /**
* Dtl constructor. * Dtl constructor.
* @param $params * @param $params
*/ * @throws Exception
public function __construct($params) */
{ public function __construct($params)
parent::__construct([]); {
$this->params = $params; parent::__construct([]);
} $this->params = $params;
}
/**
* @return array /**
* @throws Exception * @return array
*/ * @throws Exception
public function toArray(): array */
{ public function toArray(): array
if (!is_array($this->params)) { {
return ArrayAccess::toArray($this->params); return $this->params;
} }
return $this->params;
}
/**
* @param $name
/** * @return mixed
* @param $name * @throws Exception
* @return mixed */
* @throws Exception public function get($name): mixed
*/ {
public function get($name): mixed $array = $this->toArray();
{ if (!isset($array[$name])) {
$array = $this->toArray(); return null;
if (!isset($array[$name])) { }
return null; return $array[$name];
} }
return $array[$name];
}
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
namespace Kiri\Core;
use JetBrains\PhpStorm\Pure;
use ReturnTypeWillChange;
use Traversable;
class HashMap implements \ArrayAccess, \IteratorAggregate
{
/**
* @var array
*/
private array $lists = [];
/**
* @return Traversable
*/
public function getIterator(): Traversable
{
return new \ArrayIterator($this->lists);
}
/**
* @param string $key
* @param $value
*/
public function put(string $key, $value)
{
$this->lists[$key] = $value;
}
/**
* @param string $key
* @return mixed
*/
#[Pure] public function get(string $key): mixed
{
if (!$this->has($key)) {
return null;
}
return $this->lists[$key];
}
/**
* @param string $key
*/
public function del(string $key)
{
if (!$this->has($key)) {
return;
}
unset($this->lists[$key]);
}
/**
* @param string $key
* @return bool
*/
public function has(string $key): bool
{
return array_key_exists($key, $this->lists);
}
/**
* @param mixed $offset
* @return bool
*/
public function offsetExists(mixed $offset): bool
{
return isset($this->lists[$offset]);
}
/**
* @param mixed $offset
* @return mixed
*/
#[Pure] public function offsetGet(mixed $offset): mixed
{
return $this->get($offset);
}
/**
* @param mixed $offset
* @param mixed $value
*/
#[ReturnTypeWillChange]
public function offsetSet(mixed $offset, mixed $value)
{
$this->put($offset, $value);
}
/**
* @param mixed $offset
*/
#[ReturnTypeWillChange]
public function offsetUnset(mixed $offset)
{
unset($this->lists[$offset]);
}
}
+219 -215
View File
@@ -1,215 +1,219 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class Help * Class Help
* @package Kiri\Kiri\Core * @package Kiri\Core
*/ */
class Help class Help
{ {
/** /**
* @param array $data * @param array $data
* @return string * @return string
*/ */
public static function toXml(array $data): string public static function toXml(array $data): string
{ {
$xml = "<xml>"; $xml = "<xml>";
foreach ($data as $key => $val) { foreach ($data as $key => $val) {
if (is_array($val)) { if (is_array($val)) {
$xml .= "<" . $key . ">" . static::xmlChild($val) . "</" . $key . ">"; $xml .= "<" . $key . ">" . static::xmlChild($val) . "</" . $key . ">";
} else if (is_numeric($val)) { } else if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">"; $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else { } else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
} }
} }
$xml .= "</xml>"; $xml .= "</xml>";
return $xml; return $xml;
} }
/** /**
* @param array $array * @param array $array
* @return string * @return string
*/ */
private static function xmlChild(array $array): string private static function xmlChild(array $array): string
{ {
$string = ''; $string = '';
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
if (is_array($value)) { if (is_array($value)) {
$string .= static::xmlChild($value); $string .= static::xmlChild($value);
} else if (is_numeric($value)) { } else if (is_numeric($value)) {
$string .= "<" . $key . ">" . $value . "</" . $key . ">"; $string .= "<" . $key . ">" . $value . "</" . $key . ">";
} else { } else {
$string .= "<" . $key . "><![CDATA[" . $value . "]]></" . $key . ">"; $string .= "<" . $key . "><![CDATA[" . $value . "]]></" . $key . ">";
} }
} }
return $string; return $string;
} }
/** /**
* @param $xml * @param $xml
* @return mixed * @return mixed
*/ * @throws Exception
public static function toArray($xml): mixed */
{ public static function toArray($xml): mixed
if (empty($xml)) { {
return []; if (empty($xml)) {
} else if (is_array($xml)) { return [];
return $xml; } else if (is_array($xml)) {
} return $xml;
if (!($_xml = Xml::isXml($xml))) { }
return static::jsonToArray($xml); if (!($_xml = Xml::isXml($xml))) {
} return static::jsonToArray($xml);
return $_xml; }
} return $_xml;
}
/**
* @param $xml /**
* @return mixed * @param $xml
*/ * @return mixed
public static function jsonToArray($xml): mixed */
{ public static function jsonToArray($xml): mixed
$_xml = json_decode($xml, true); {
if (is_null($_xml)) { $_xml = json_decode($xml, true);
return []; if (is_null($_xml)) {
} return [];
return $_xml; }
} return $_xml;
}
/**
* @param $xml /**
* @return mixed * @param $xml
*/ * @return mixed
public static function xmlToArray($xml): mixed */
{ public static function xmlToArray($xml): mixed
if (is_array($xml)) { {
return $xml; if (is_array($xml)) {
} return $xml;
if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) { }
return json_decode(json_encode($data), TRUE); if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) {
} return json_decode(json_encode($data), TRUE);
if (!is_null($json = json_decode($xml, TRUE))) { }
return $json; if (!is_null($json = json_decode($xml, TRUE))) {
} return $json;
return $xml; }
} return $xml;
}
/**
* @param $parameter /**
* @return array|false|string * @param $parameter
* @throws Exception * @return array|false|string
*/ * @throws Exception
public static function toString($parameter): bool|array|string */
{ public static function toString($parameter): bool|array|string
if (!is_string($parameter)) { {
$parameter = ArrayAccess::toArray($parameter); if (!is_string($parameter)) {
if (is_array($parameter)) { $parameter = ArrayAccess::toArray($parameter);
$parameter = Json::encode($parameter); if (is_array($parameter)) {
} $parameter = Json::encode($parameter);
} }
return $parameter; }
} return $parameter;
}
/**
* @param mixed $json /**
* @return bool|string * @param mixed $json
*/ * @return bool|string
public static function toJson(mixed $json): bool|string */
{ public static function toJson(mixed $json): bool|string
if (is_object($json)) { {
$json = get_object_vars($json); if (is_object($json)) {
} $json = get_object_vars($json);
if (is_array($json)) { }
return json_encode($json, JSON_UNESCAPED_UNICODE); if (is_array($json)) {
} return json_encode($json, JSON_UNESCAPED_UNICODE);
$matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/'; }
if (preg_match($matchQuote, $json)) { $matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/';
$json = self::xmlToArray($json); if (preg_match($matchQuote, $json)) {
} else { $json = self::xmlToArray($json);
$json = json_decode($json, true); } else {
} $json = json_decode($json, true);
if (!is_array($json)) { }
$json = []; if (!is_array($json)) {
} $json = [];
return json_encode($json, JSON_UNESCAPED_UNICODE); }
} return json_encode($json, JSON_UNESCAPED_UNICODE);
}
/**
* @param int $length /**
* @return string * @param int $length
* * @return string
* 随机字符串 *
*/ * 随机字符串
public static function random($length = 20): string */
{ public static function random($length = 20): string
$res = []; {
$str = 'abcdefghijklmnopqrstuvwxyz'; $res = [];
$str .= strtoupper($str) . '1234567890'; $str = 'abcdefghijklmnopqrstuvwxyz';
for ($i = 0; $i < $length; $i++) { $str .= strtoupper($str) . '1234567890';
$rand = substr($str, rand(0, strlen($str) - 2), 1); for ($i = 0; $i < $length; $i++) {
if (empty($rand)) { $rand = substr($str, rand(0, strlen($str) - 2), 1);
$rand = substr($str, strlen($str) - 3, 1); if (empty($rand)) {
} $rand = substr($str, strlen($str) - 3, 1);
array_push($res, $rand); }
} array_push($res, $rand);
}
return implode($res);
} return implode($res);
}
/**
* @param array $array /**
* @param $key * @param array $array
* @param string $type * @param $key
* @return string * @param string $type
*/ * @return string
public static function sign(array $array, $key, string $type = 'MD5'): string */
{ public static function sign(array $array, $key, string $type = 'MD5'): string
ksort($array, SORT_ASC); {
$string = []; ksort($array, SORT_ASC);
foreach ($array as $hashKey => $val) { $string = [];
if (empty($val)) { foreach ($array as $hashKey => $val) {
continue; if (empty($val)) {
} continue;
$string[] = $hashKey . '=' . $val; }
} $string[] = $hashKey . '=' . $val;
$string[] = 'key=' . $key; }
$string = implode('&', $string); $string[] = 'key=' . $key;
if ($type == 'MD5') { $string = implode('&', $string);
return strtoupper(md5($string)); if ($type == 'MD5') {
} else { return strtoupper(md5($string));
return hash('sha256', $string); } else {
} return hash('sha256', $string);
} }
}
/**
* @param $email /**
* @param string $Subject * @param $email
* @param $messageContent * @param string $Subject
*/ * @param $messageContent
public static function sendEmail($email, string $Subject, $messageContent) */
{ public static function sendEmail($email, string $Subject, $messageContent)
$mailer = new \Swift_Mailer((new \Swift_SmtpTransport($email['host'], $email['port'])) {
->setUsername($email['username'])->setPassword($email['password'])); if (!class_exists('\Swift_Mailer')) {
$message = (new \Swift_Message($Subject)) return;
->setFrom([$email['send']['address'] => $email['send']['nickname']]) }
->setBody('Here is the message itself'); $mailer = new \Swift_Mailer((new \Swift_SmtpTransport($email['host'], $email['port']))
->setUsername($email['username'])->setPassword($email['password']));
foreach ($email['receive'] as $item) { $message = (new \Swift_Message($Subject))
$message->setTo([$item['address'], $item['address'] => $item['nickname']]); ->setFrom([$email['send']['address'] => $email['send']['nickname']])
} ->setBody('Here is the message itself');
$mailer->send($messageContent);
} foreach ($email['receive'] as $item) {
$message->setTo([$item['address'], $item['address'] => $item['nickname']]);
} }
$mailer->send($messageContent);
}
}
+121 -122
View File
@@ -1,122 +1,121 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-20 * Date: 2019-03-20
* Time: 01:04 * Time: 01:04
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Error; use Error;
use Exception; use Exception;
use Throwable; use Throwable;
/** /**
* Class JSON * Class JSON
* @package Kiri\Kiri\Core * @package Kiri\Core
*/ */
class Json class Json
{ {
/** /**
* @param $data * @param $data
* @return false|string * @return false|string
*/ */
public static function encode($data): bool|string public static function encode($data): bool|string
{ {
if (empty($data)) { if (empty($data)) {
return false; return false;
} }
if (is_array($data)) { if (is_array($data)) {
return json_encode($data, JSON_UNESCAPED_UNICODE); return json_encode($data, JSON_UNESCAPED_UNICODE);
} }
return $data; return $data;
} }
/** /**
* @param $data * @param $data
* @param bool $asArray * @param bool $asArray
* @return mixed * @return mixed
*/ */
public static function decode($data, $asArray = true): mixed public static function decode($data, bool $asArray = true): mixed
{ {
if (is_array($data) || is_numeric($data)) { if (is_array($data) || is_numeric($data)) {
return $data; return $data;
} }
if (!is_string($data)) return null; if (!is_string($data)) return null;
return json_decode($data, $asArray); return json_decode($data, $asArray);
} }
/** /**
* @param $code * @param $code
* @param string $message * @param string|array $message
* @param array $data * @param array|int $data
* @param int $count * @param int $count
* @param array $exPageInfo * @param array $exPageInfo
* @return mixed * @return string|bool
* @throws */
*/ public static function to($code, string|array $message = '', array|int $data = [], int $count = 0, array $exPageInfo = []): string|bool
public static function to($code, $message = '', $data = [], $count = 0, $exPageInfo = []): mixed {
{ $params['code'] = $code;
$params['code'] = $code; if (!is_string($message)) {
if (!is_string($message)) { $params['message'] = 'System success.';
$params['param'] = $message; $params['param'] = $message;
if (!empty($data)) { if (!empty($data)) {
$params['exPageInfo'] = $data; $params['exPageInfo'] = $data;
} }
$params['message'] = 'System success.'; } else {
} else { $params['message'] = $message;
$params['message'] = $message; $params['param'] = $data;
$params['param'] = $data; }
} if (!empty($exPageInfo)) {
if (!empty($exPageInfo)) { $params['exPageInfo'] = $exPageInfo;
$params['exPageInfo'] = $exPageInfo; }
} $params['count'] = $count;
$params['count'] = $count; if (is_numeric($data) || !is_numeric($count)) {
if (is_numeric($data) || !is_numeric($count)) { $params['count'] = $data;
$params['count'] = $data; $params['exPageInfo'] = $count;
$params['exPageInfo'] = $count; }
} if ((int)$params['count'] == -100) {
if ((int)$params['count'] == -100) { $params['count'] = 1;
$params['count'] = 1; }
} return static::encode($params);
return static::encode($params); }
}
/**
/** * @param Throwable|Error $throwable
* @param Throwable|Error $throwable * @return bool|string
* @return bool|string */
*/ public static function error(Throwable|Error $throwable): bool|string
public static function error(Throwable|Error $throwable): bool|string {
{ $array['code'] = $throwable->getCode() == 0 ? 500 : $throwable->getCode();
$array['code'] = $throwable->getCode() == 0 ? 500 : $throwable->getCode(); $array['message'] = $throwable->getMessage();
$array['message'] = $throwable->getMessage(); $array['param'] = [
$array['param'] = [ 'file' => $throwable->getFile(),
'file' => $throwable->getFile(), 'line' => $throwable->getLine()
'line' => $throwable->getLine() ];
]; return Json::encode($array);
return Json::encode($array); }
}
/**
/** * @param $state
* @param $state * @param $body
* @param $body * @return false|int|string
* @return false|int|string * @throws Exception
* @throws Exception */
*/ public static function output($state, $body): bool|int|string
public static function output($state, $body): bool|int|string {
{ $params['state'] = $state;
$params['state'] = $state; $params['body'] = ArrayAccess::toArray($body);
$params['body'] = ArrayAccess::toArray($body);
return static::encode($params);
return static::encode($params); }
} }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Kiri\Core;
class Network
{
/**
* @return string
*/
public static function local(): string
{
return current(swoole_get_local_ip());
}
}
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
namespace Kiri\Core; namespace Kiri\Core;
class Number class Number
{ {
/** /**
* @param int $userId * @param int $userId
* @return string * @return string
*/ */
public static function order(int $userId): string public static function order(int $userId): string
{ {
$explode = current(explode(' ', str_replace('0.', '', microtime()))); $explode = current(explode(' ', str_replace('0.', '', microtime())));
return 'No.' . sprintf('%010d', $userId) . '.' . date('Ymd.His') . '.' . $explode; return 'No.' . sprintf('%010d', $userId) . '.' . date('Ymd.His') . '.' . $explode;
} }
/** /**
* @param int $userId * @param int $userId
* @return string * @return string
*/ */
public static function create(int $userId): string public static function create(int $userId): string
{ {
return static::order($userId); return static::order($userId);
} }
} }
+172 -172
View File
@@ -1,172 +1,172 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
/** /**
* Class Reader * Class Reader
* @package Kiri\Kiri\Core * @package Kiri\Core
*/ */
class Reader class Reader
{ {
/** /**
* @param $filepath * @param $filepath
* @param int $page * @param int $page
* @param int $size * @param int $size
* @return array and int * @return array and int
*/ */
public static function readerServerLogPagination($filepath, int $page = 1, int $size = 20): array public static function readerServerLogPagination($filepath, int $page = 1, int $size = 20): array
{ {
$count = 0; $count = 0;
$strings = []; $strings = [];
$offset = ($page - 1) * $size; $offset = ($page - 1) * $size;
if (!file_exists($filepath)) { if (!file_exists($filepath)) {
return [0, []]; return [0, []];
} }
//只读方式打开文件 //只读方式打开文件
$fp = fopen($filepath, "r"); $fp = fopen($filepath, "r");
//开始循环读取$buffer_size //开始循环读取$buffer_size
while (!feof($fp)) { while (!feof($fp)) {
//读文件到缓冲区 //读文件到缓冲区
$buffer = fgets($fp); $buffer = fgets($fp);
$count++; $count++;
if ($count > $offset && count($strings) < $size) { if ($count > $offset && count($strings) < $size) {
$strings[] = [ $strings[] = [
'id' => $count, 'id' => $count,
'content' => $buffer 'content' => $buffer
]; ];
} }
} }
//关闭文件 //关闭文件
fclose($fp); fclose($fp);
unset($fp); unset($fp);
return ['total' => $count, 'list' => $strings]; return ['total' => $count, 'list' => $strings];
} }
/** /**
* @param $filename * @param $filename
* @param $start * @param $start
* @param $lines * @param $lines
* @return array * @return array
*/ */
public static function read_backward_line($filename, $start, $lines): array public static function read_backward_line($filename, $start, $lines): array
{ {
$lines++; $lines++;
$offset = -1; $offset = -1;
$read = ''; $read = '';
$fp = @fopen($filename, "r"); $fp = @fopen($filename, "r");
$tmpStart = 0; $tmpStart = 0;
while ($lines && fseek($fp, $offset, SEEK_END) >= 0) { while ($lines && fseek($fp, $offset, SEEK_END) >= 0) {
$c = fgetc($fp); $c = fgetc($fp);
if ($c == "\n" || $c == "\r") { if ($c == "\n" || $c == "\r") {
if (++$tmpStart >= $start) if (++$tmpStart >= $start)
$lines--; $lines--;
} }
if ($tmpStart >= $start) if ($tmpStart >= $start)
$read .= $c; $read .= $c;
$offset--; $offset--;
} }
$read = trim($read); $read = trim($read);
$contents = []; $contents = [];
$read = array_reverse(explode("\n", strrev($read))); $read = array_reverse(explode("\n", strrev($read)));
foreach ($read as $key => $value) { foreach ($read as $key => $value) {
if (empty($value)) { if (empty($value)) {
unset($read[$key]); unset($read[$key]);
} else { } else {
$contents[] = ['content' => $value, 'id' => $key + $start]; $contents[] = ['content' => $value, 'id' => $key + $start];
} }
} }
$response['total'] = self::read_count_by_file($filename); $response['total'] = self::read_count_by_file($filename);
$response['list'] = $contents; $response['list'] = $contents;
return $response; return $response;
} }
/** /**
* @param $filepath * @param $filepath
* @return int * @return int
*/ */
private static function read_count_by_file($filepath): int private static function read_count_by_file($filepath): int
{ {
$count = 0; $count = 0;
//只读方式打开文件 //只读方式打开文件
$fp = fopen($filepath, "r"); $fp = fopen($filepath, "r");
//开始循环读取$buffer_size //开始循环读取$buffer_size
while (fgets($fp)) { while (fgets($fp)) {
$count++; $count++;
} }
//关闭文件 //关闭文件
fclose($fp); fclose($fp);
unset($fp); unset($fp);
return $count; return $count;
} }
/** /**
* @param $filepath * @param $filepath
* @param int $page * @param int $page
* @param int $size * @param int $size
* @return array * @return array
*/ */
public static function folderPagination($filepath, int $page = 1, int $size = 20): array public static function folderPagination($filepath, int $page = 1, int $size = 20): array
{ {
$count = 0; $count = 0;
$strings = []; $strings = [];
$offset = ($page - 1) * $size; $offset = ($page - 1) * $size;
if (!is_dir($filepath)) { if (!is_dir($filepath)) {
return [0, []]; return [0, []];
} }
foreach (glob($filepath . '/*') as $key => $value) { foreach (glob($filepath . '/*') as $key => $value) {
$count++; $count++;
if ($key < $offset || count($strings) >= $size) { if ($key < $offset || count($strings) >= $size) {
continue; continue;
} }
$explode = explode(DIRECTORY_SEPARATOR, $value); $explode = explode(DIRECTORY_SEPARATOR, $value);
$addTime = fileatime($value); $addTime = fileatime($value);
$changeTime = filectime($value); $changeTime = filectime($value);
$modifyTime = filemtime($value); $modifyTime = filemtime($value);
$strings[] = [ $strings[] = [
'id' => $count, 'id' => $count,
'path' => $value, 'path' => $value,
'isDir' => (int)is_dir($value), 'isDir' => (int)is_dir($value),
'name' => end($explode), 'name' => end($explode),
'atime' => [ 'atime' => [
'format' => date('Y-m-d H:i:s', $addTime), 'format' => date('Y-m-d H:i:s', $addTime),
'microtime' => $addTime 'microtime' => $addTime
], ],
'ctime' => [ 'ctime' => [
'format' => date('Y-m-d H:i:s', $changeTime), 'format' => date('Y-m-d H:i:s', $changeTime),
'microtime' => $changeTime 'microtime' => $changeTime
], ],
'mtime' => [ 'mtime' => [
'format' => date('Y-m-d H:i:s', $modifyTime), 'format' => date('Y-m-d H:i:s', $modifyTime),
'microtime' => $modifyTime 'microtime' => $modifyTime
], ],
]; ];
} }
array_multisort($strings, array_column($strings, 'isDir'), SORT_DESC); array_multisort($strings, array_column($strings, 'isDir'), SORT_DESC);
return ['total' => $count, 'list' => $strings]; return ['total' => $count, 'list' => $strings];
} }
} }
+283 -283
View File
@@ -1,283 +1,283 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class Str * Class Str
* @package Kiri\Kiri\Core * @package Kiri\Core
*/ */
class Str class Str
{ {
const STRING = 'abcdefghijklmnopqrstuvwxyz'; const STRING = 'abcdefghijklmnopqrstuvwxyz';
const NUMBER = '01234567890'; const NUMBER = '01234567890';
/** /**
* @param int $length * @param int $length
* *
* @return string * @return string
* 获取随机字符串 * 获取随机字符串
*/ */
public static function rand(int $length = 20): string public static function rand(int $length = 20): string
{ {
$string = ''; $string = '';
if ($length < 1) $length = 20; if ($length < 1) $length = 20;
$default = self::STRING . strtoupper(self::STRING) . self::NUMBER; $default = self::STRING . strtoupper(self::STRING) . self::NUMBER;
$default = str_split($default); $default = str_split($default);
for ($i = 0; $i < $length; $i++) { for ($i = 0; $i < $length; $i++) {
shuffle($default); shuffle($default);
$string .= $default[array_rand($default)]; $string .= $default[array_rand($default)];
} }
return $string; return $string;
} }
/** /**
* @param int $length * @param int $length
* *
* @return int|string 获取随机数字 * @return int|string 获取随机数字
* 获取随机数字 * 获取随机数字
*/ */
public static function random(int $length = 20): int|string public static function random(int $length = 20): int|string
{ {
$number = ''; $number = '';
$default = str_split(self::NUMBER); $default = str_split(self::NUMBER);
if ($length < 1) $length = 1; if ($length < 1) $length = 1;
for ($i = 0; $i < $length; $i++) { for ($i = 0; $i < $length; $i++) {
shuffle($default); shuffle($default);
$number .= $default[array_rand($default)]; $number .= $default[array_rand($default)];
} }
return $number; return $number;
} }
/** /**
* @param $string * @param $string
* @param $sullen * @param $sullen
* @param bool $strip_tags * @param bool $strip_tags
* @param string $append * @param string $append
* *
* @return string * @return string
*/ */
public static function cut_str_utf8($string, $sullen, bool $strip_tags = TRUE, string $append = '...'): string public static function cut_str_utf8($string, $sullen, bool $strip_tags = TRUE, string $append = '...'): string
{ {
if ($strip_tags) { if ($strip_tags) {
$string = strip_tags($string); $string = strip_tags($string);
}//去掉签标 }//去掉签标
$pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/"; $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
preg_match_all($pa, $string, $t_string); preg_match_all($pa, $string, $t_string);
$str = ""; $str = "";
for ($i = 0; $i < count($t_string[0]); $i++) { for ($i = 0; $i < count($t_string[0]); $i++) {
$str .= $t_string[0][$i]; $str .= $t_string[0][$i];
//转为gbk,一个汉字长度为2 //转为gbk,一个汉字长度为2
if (strlen(@iconv('utf-8', 'gbk', $str)) >= $sullen) { if (strlen(@iconv('utf-8', 'gbk', $str)) >= $sullen) {
if ($i != count($t_string[0]) - 1) $str .= $append; if ($i != count($t_string[0]) - 1) $str .= $append;
break; break;
} }
} }
return $str; return $str;
} }
/** /**
* @param $data * @param $data
* *
* @param null $callback * @param null $callback
* @return bool * @return bool
* 判断是否为json字符串 * 判断是否为json字符串
*/ */
public static function isJson($data, $callback = NULL): bool public static function isJson($data, $callback = NULL): bool
{ {
$json = !is_null(json_decode($data)) && !is_numeric($data); $json = !is_null(json_decode($data)) && !is_numeric($data);
if ($json && is_callable($callback, TRUE)) { if ($json && is_callable($callback, TRUE)) {
return call_user_func($callback, $data); return call_user_func($callback, $data);
} }
return $json; return $json;
} }
/** /**
* @param $data * @param $data
* *
* @param null $callBack * @param null $callBack
* @return bool * @return bool
* 判断是否序列化字符串 * 判断是否序列化字符串
*/ */
public static function isSerialize($data, $callBack = NULL): bool public static function isSerialize($data, $callBack = NULL): bool
{ {
$false = !empty($data) && swoole_unserialize($data) !== FALSE; $false = !empty($data) && swoole_unserialize($data) !== FALSE;
if ($false && is_callable($callBack, TRUE)) { if ($false && is_callable($callBack, TRUE)) {
return call_user_func($callBack, $data); return call_user_func($callBack, $data);
} }
return $false; return $false;
} }
/** /**
* @param $string * @param $string
* @param int $length * @param int $length
* *
* @param string $append * @param string $append
* @return string * @return string
*/ */
public static function cut($string, int $length = 20, string $append = '...'): string public static function cut($string, int $length = 20, string $append = '...'): string
{ {
if (empty($string)) { if (empty($string)) {
return ''; return '';
} }
if ($length < 1) { if ($length < 1) {
$length = 1; $length = 1;
} }
$array = str_split($string); $array = str_split($string);
if (count($array) <= $length) { if (count($array) <= $length) {
return implode('', $array); return implode('', $array);
} }
$string = implode('', array_slice($array, 0, $length)); $string = implode('', array_slice($array, 0, $length));
if (!empty($append)) { if (!empty($append)) {
$string .= $append; $string .= $append;
} }
return $string; return $string;
} }
/** /**
* @param $str * @param $str
* @param int $number * @param int $number
* @param string $key * @param string $key
* *
* @return string * @return string
*/ */
public static function encrypt($str, int $number = 10, string $key = 'xshucai.com'): string public static function encrypt($str, int $number = 10, string $key = 'xshucai.com'): string
{ {
$res = []; $res = [];
$add = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $add = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$len = strlen($key) < 0 ? 1 : (strlen($key) + 5 > strlen($add) ? strlen($add) - 5 : strlen($key)); $len = strlen($key) < 0 ? 1 : (strlen($key) + 5 > strlen($add) ? strlen($add) - 5 : strlen($key));
if ($number < 1) $number = 10; if ($number < 1) $number = 10;
$array = str_split($str); $array = str_split($str);
asort($array); asort($array);
$str = implode('', $array); $str = implode('', $array);
for ($i = 0; $i < $number; $i++) { for ($i = 0; $i < $number; $i++) {
$_tmp = md5($key) . md5($str) . mb_substr($add, $len, $len + 5, 'utf-8'); $_tmp = md5($key) . md5($str) . mb_substr($add, $len, $len + 5, 'utf-8');
$res[] = md5($_tmp); $res[] = md5($_tmp);
} }
sort($res, SORT_STRING); sort($res, SORT_STRING);
return hash('sha384', implode('', $res)); return hash('sha384', implode('', $res));
} }
/** /**
* @param $file * @param $file
* @param $type * @param $type
* @return string * @return string
*/ */
public static function filename($file, $type): string public static function filename($file, $type): string
{ {
switch ($type) { switch ($type) {
case 'image/png': case 'image/png':
return md5_file($file) . '.png'; return md5_file($file) . '.png';
case 'image/jpeg': case 'image/jpeg':
case 'image/jpg': case 'image/jpg':
return md5_file($file) . '.jpg'; return md5_file($file) . '.jpg';
case 'image/gif': case 'image/gif':
return md5_file($file) . '.gif'; return md5_file($file) . '.gif';
break; break;
} }
return md5_file($file); return md5_file($file);
} }
/** /**
* @param $endTime * @param $endTime
* @param int|null $startTime * @param int|null $startTime
* @return array * @return array
* 剩余天,带分秒 * 剩余天,带分秒
*/ */
public static function timeout($endTime, int $startTime = NULL): array public static function timeout($endTime, int $startTime = NULL): array
{ {
$endTime = $endTime - (!empty($startTime) ? $startTime : time()); $endTime = $endTime - (!empty($startTime) ? $startTime : time());
$day = intval($endTime / (3600 * 24)); $day = intval($endTime / (3600 * 24));
$hours = intval(($endTime - ($day * (3600 * 24))) / 3600); $hours = intval(($endTime - ($day * (3600 * 24))) / 3600);
$minute = intval(($endTime - ($day * (3600 * 24) + $hours * 3600)) / 60); $minute = intval(($endTime - ($day * (3600 * 24) + $hours * 3600)) / 60);
$scrod = intval(($endTime - ($day * (3600 * 24) + $hours * 3600 + $minute * 60))); $scrod = intval(($endTime - ($day * (3600 * 24) + $hours * 3600 + $minute * 60)));
return [$day, $hours, $minute, $scrod]; return [$day, $hours, $minute, $scrod];
} }
/** /**
* @return false|int * @return false|int
*/ */
public static function get_sy_time(): bool|int public static function get_sy_time(): bool|int
{ {
$time = strtotime('+1days', strtotime(date('Y-m-d'))); $time = strtotime('+1days', strtotime(date('Y-m-d')));
return $time - time(); return $time - time();
} }
/** /**
* @param string $string * @param string $string
* @return string * @return string
*/ */
public static function encode(string $string): string public static function encode(string $string): string
{ {
return addslashes($string); return addslashes($string);
} }
/** /**
* @param string $string * @param string $string
* @return string|string[]|null * @return string|string[]|null
* 清除标点符号 * 清除标点符号
*/ */
public static function clear(string $string): array|string|null public static function clear(string $string): array|string|null
{ {
$char = '。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()'; $char = '。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()';
return preg_replace(["/[[:punct:]]/i", '/[' . $char . ']/u', '/[ ]{2,}/'], '', $string); return preg_replace(["/[[:punct:]]/i", '/[' . $char . ']/u', '/[ ]{2,}/'], '', $string);
} }
/** /**
* @param int $user * @param int $user
* @param array $param * @param array $param
* @param null $requestTime * @param null $requestTime
* *
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public static function token(int $user, array $param = [], $requestTime = NULL): string public static function token(int $user, array $param = [], $requestTime = NULL): string
{ {
$str = ''; $str = '';
if (!$requestTime) { if (!$requestTime) {
$requestTime = microtime(TRUE); $requestTime = microtime(TRUE);
} }
$_user = str_split(md5($user . md5((string)$user))); $_user = str_split(md5($user . md5((string)$user)));
ksort($_user); ksort($_user);
foreach ($_user as $key => $val) { foreach ($_user as $key => $val) {
$str .= md5(sha1($key . $val . 'www.xshucai.com')); $str .= md5(sha1($key . $val . 'www.xshucai.com'));
} }
if (is_array($param)) { if (is_array($param)) {
foreach ($param as $key => $val) { foreach ($param as $key => $val) {
$str .= md5($str . sha1($key . md5($val))); $str .= md5($str . sha1($key . md5($val)));
} }
} }
$str .= sha1(base64_encode((string)$requestTime)); $str .= sha1(base64_encode((string)$requestTime));
$md5 = md5($str . $user); $md5 = md5($str . $user);
return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $md5); return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $md5);
} }
/** /**
* @param string $str * @param string $str
* @param bool $unfairest * @param bool $unfairest
* @return string * @return string
*/ */
public static function convertUnderline(string $str, bool $unfairest = TRUE): string public static function convertUnderline(string $str, bool $unfairest = TRUE): string
{ {
$str = ucwords(str_replace('_', ' ', $str)); $str = ucwords(str_replace('_', ' ', $str));
$str = str_replace(' ', '', lcfirst($str)); $str = str_replace(' ', '', lcfirst($str));
return $unfairest ? ucfirst($str) : $str; return $unfairest ? ucfirst($str) : $str;
} }
} }
+57 -57
View File
@@ -1,57 +1,57 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-20 * Date: 2019-03-20
* Time: 01:03 * Time: 01:03
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class Xml * Class Xml
* @package Kiri\Kiri\Core * @package Kiri\Core
*/ */
class Xml class Xml
{ {
/** /**
* @param $data * @param $data
* @param bool $asArray * @param bool $asArray
* @return array|object * @return array|object
* @throws Exception * @throws Exception
*/ */
public static function toArray($data, bool $asArray = true): object|array public static function toArray($data, bool $asArray = true): object|array
{ {
$data = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA); $data = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
if ($data === false) { if ($data === false) {
throw new Exception('Parameter format error.'); throw new Exception('Parameter format error.');
} }
$array = get_object_vars($data); $array = get_object_vars($data);
if (isset($array[0])) { if (isset($array[0])) {
$array[$data->getName()] = $array[0]; $array[$data->getName()] = $array[0];
unset($array[0]); unset($array[0]);
} }
return $array; return $array;
} }
/** /**
* @param $str * @param $str
* @return array|bool|object * @return array|bool|object
* @throws Exception * @throws Exception
*/ */
public static function isXml($str): object|bool|array public static function isXml($str): object|bool|array
{ {
$xml_parser = xml_parser_create(); $xml_parser = xml_parser_create();
if (!xml_parse($xml_parser, $str, true)) { if (!xml_parse($xml_parser, $str, true)) {
xml_parser_free($xml_parser); xml_parser_free($xml_parser);
return false; return false;
} else { } else {
return self::toArray($str); return self::toArray($str);
} }
} }
} }
-461
View File
@@ -1,461 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: whwyy
* Date: 2018/4/24 0024
* Time: 17:27
*/
declare(strict_types=1);
namespace Kiri\Di;
use Annotation\Inject;
use Closure;
use Exception;
use Kiri\Abstracts\BaseObject;
use Kiri\Abstracts\Logger;
use Kiri\Kiri;
use Psr\Log\LoggerInterface;
use ReflectionClass;
use ReflectionException;
use ReflectionFunction;
use ReflectionMethod;
use ReflectionProperty;
use Psr\Container\ContainerInterface;
/**
* Class Container
* @package Kiri\Di
*/
class Container extends BaseObject implements ContainerInterface
{
/**
* @var array
*
* instance class by className
*/
private array $_singletons = [];
/**
* @var ReflectionMethod[]
*
* class new instance construct parameter
*/
private array $_constructs = [];
/**
* @var array
*
* implements \ReflectClass
*/
private array $_reflection = [];
/** @var array */
private array $_parameters = [];
/** @var array|string[] */
private array $_interfaces = [
LoggerInterface::class => Logger::class
];
/**
* @param string $id
* @return mixed
* @throws ReflectionException
*/
public function get(string $id): mixed
{
return $this->make($id, [], []);
}
/**
* @param $class
* @param array $constrict
* @param array $config
* @return mixed
* @throws ReflectionException
* @throws Exception
*/
public function make($class, array $constrict = [], array $config = []): mixed
{
if ($this->isInterface($class)) {
$class = $this->_interfaces[$class];
}
if (!isset($this->_singletons[$class])) {
$this->_singletons[$class] = $this->resolve($class, $constrict, $config);
}
return $this->_singletons[$class];
}
/**
* @param string $interface
* @param string $class
*/
public function mapping(string $interface, string $class)
{
$this->_interfaces[$interface] = $class;
}
/**
* @param $class
* @return bool
* @throws ReflectionException
*/
public function isInterface($class): bool
{
$reflect = $this->getReflect($class);
if ($reflect->isInterface()) {
return true;
}
return false;
}
/**
* @param string $interface
* @param $object
*/
public function setBindings(string $interface, $object)
{
if (is_string($object)) {
$this->_interfaces[$interface] = $object;
} else {
$className = get_class($object);
$this->_interfaces[$interface] = $className;
$this->_singletons[$className] = $object;
}
}
/**
* @param $class
* @param array $constrict
* @param array $config
* @return object
* @throws
*/
public function create($class, array $constrict = [], array $config = []): object
{
return $this->resolve($class, $constrict, $config);
}
/**
* @param $class
* @param $constrict
* @param $config
*
* @return object
* @throws Exception
*/
private function resolve($class, $constrict, $config): object
{
$reflect = $this->resolveDependencies($class);
if (!$reflect->isInstantiable()) {
throw new ReflectionException('Class ' . $class . ' cannot be instantiated');
}
$object = $this->newInstance($reflect, $constrict);
$this->propertyInject($reflect, $object);
return $this->onAfterInit($object, $config);
}
/**
* @param ReflectionClass $reflect
* @param $dependencies
* @return object
* @throws ReflectionException
*/
private function newInstance(ReflectionClass $reflect, $dependencies): object
{
if (!isset($this->_constructs[$reflect->getName()])) {
return $reflect->newInstance();
}
$construct = $this->_constructs[$reflect->getName()];
if ($construct->getNumberOfParameters() < 1) {
return $reflect->newInstance();
}
$parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies);
return $reflect->newInstanceArgs($parameters);
}
/**
* @param ReflectionClass $reflect
* @param $object
* @return mixed
* @throws Exception
*/
public function propertyInject(ReflectionClass $reflect, $object): mixed
{
foreach (NoteManager::getPropertyNote($reflect) as $property => $inject) {
/** @var Inject $inject */
$inject->execute($object, $property);
}
return $object;
}
/**
* @param $className
* @param $method
* @return array
* @throws ReflectionException
*/
public function getMethodAttribute($className, $method = null): array
{
$methods = NoteManager::getMethodNote($this->getReflect($className));
if (!empty($method)) {
return $methods[$method] ?? [];
}
return $methods;
}
/**
* @param string $class
* @param string|null $property
* @return ReflectionProperty|ReflectionProperty[]|null
* @throws ReflectionException
*/
public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array
{
$lists = NoteManager::getProperty($this->getReflect($class));
if (empty($lists)) {
return null;
}
if (!empty($property)) {
return $lists[$property] ?? null;
}
return $lists;
}
/**
* @param $object
* @param $config
* @return mixed
*/
private function onAfterInit($object, $config): mixed
{
Kiri::configure($object, $config);
if (method_exists($object, 'init') && is_callable([$object, 'init'])) {
call_user_func([$object, 'init']);
}
return $object;
}
/**
* @param $class
* @return ReflectionClass
* @throws ReflectionException
*/
private function resolveDependencies($class): ReflectionClass
{
if (isset($this->_reflection[$class])) {
return $this->_reflection[$class];
}
$reflect = new ReflectionClass($class);
if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) {
return $this->_reflection[$class] = $reflect;
}
$construct = NoteManager::resolveTarget($reflect);
if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
$this->_constructs[$class] = $construct;
}
return $this->_reflection[$class] = $reflect;
}
/**
* @param ReflectionClass|string $class
* @return ReflectionMethod[]
* @throws ReflectionException
*/
public function getReflectMethods(ReflectionClass|string $class): array
{
if (is_string($class)) {
$class = $this->getReflect($class);
}
return NoteManager::getMethods($class);
}
/**
* @param ReflectionClass|string $class
* @param string $method
* @return ReflectionMethod|null
* @throws ReflectionException
*/
public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
{
return $this->getReflectMethods($class)[$method] ?? null;
}
/**
* @param string $className
* @param string $method
* @return array|null
* @throws ReflectionException
*/
public function getMethodParameters(string $className, string $method): ?array
{
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) {
return $this->_parameters[$className][$method];
}
$reflectMethod = $this->getReflectMethod($this->getReflect($className), $method);
if (!($reflectMethod instanceof ReflectionMethod)) {
throw new ReflectionException("Class does not have a function $className::$method");
}
$className = $reflectMethod->getDeclaringClass()->getName();
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) {
return $this->_parameters[$className][$reflectMethod->getName()];
}
return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod));
}
/**
* @param $class
* @param $method
* @param $parameters
* @return mixed
*/
private function setParameters($class, $method, $parameters): mixed
{
if (!isset($this->_parameters[$class])) {
$this->_parameters[$class] = [];
}
if (!isset($this->_parameters[$class][$method])) {
$this->_parameters[$class][$method] = [];
}
return $this->_parameters[$class][$method] = $parameters;
}
/**
* @param Closure $reflectionMethod
* @return array
* @throws ReflectionException
*/
public function getFunctionParameters(Closure $reflectionMethod): array
{
return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod));
}
/**
* @param ReflectionMethod|ReflectionFunction $reflectionMethod
* @return array
* @throws ReflectionException
*/
private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array
{
if ($reflectionMethod->getNumberOfParameters() < 1) {
return [];
}
$params = [];
foreach ($reflectionMethod->getParameters() as $key => $parameter) {
if ($parameter->isDefaultValueAvailable()) {
$params[$key] = $parameter->getDefaultValue();
} else if ($parameter->getType() === null) {
$params[$key] = $parameter->getType();
} else {
$type = $parameter->getType()->getName();
if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) {
$type = Kiri::getDi()->get($type);
}
$params[$key] = match ($parameter->getType()) {
'string' => '',
'int', 'float' => 0,
'', null, 'object', 'mixed' => NULL,
'bool' => false,
default => $type
};
}
}
return $params;
}
/**
* @param $class
* @return ReflectionClass|null
* @throws ReflectionException
*/
public function getReflect($class): ?ReflectionClass
{
if (!isset($this->_reflection[$class])) {
return $this->resolveDependencies($class);
}
return $this->_reflection[$class];
}
/**
* @param $class
*/
public function unset($class)
{
if (is_array($class) && isset($class['class'])) {
$class = $class['class'];
} else if (is_object($class)) {
$class = $class::class;
}
unset(
$this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class]
);
}
/**
* @return $this
*/
public function flush(): static
{
$this->_reflection = [];
$this->_singletons = [];
$this->_constructs = [];
return $this;
}
/**
* @param $old
* @param $newParam
*
* @return mixed
*/
private function mergeParam($old, $newParam): array
{
if (empty($old)) {
return $newParam;
} else if (empty($newParam)) {
return $old;
}
foreach ($newParam as $key => $val) {
$old[$key] = $val;
}
return $old;
}
/**
* @param string $id
* @return bool
*/
public function has(string $id): bool
{
return isset($this->_singletons[$id]) || isset($this->_interfaces[$id]);
}
}
-88
View File
@@ -1,88 +0,0 @@
<?php
namespace Kiri\Di;
use Kiri\Abstracts\Component;
use Kiri\Kiri;
/**
* 服务定位器
*/
class LocalService extends Component
{
private array $_components = [];
private array $_definition = [];
/**
* @param $name
* @param $define
*/
public function set($name, $define)
{
unset($this->_components[$name]);
$this->_definition[$name] = $define;
if (is_object($define) || $define instanceof \Closure) {
$this->_components[$name] = $define;
}
}
/**
* @throws \Exception
*/
public function get(string $name, $throwException = true)
{
if (isset($this->_components[$name])) {
return $this->_components[$name];
}
if (isset($this->_definition[$name])) {
$definition = $this->_definition[$name];
if (is_object($definition) && !$definition instanceof \Closure) {
return $this->_components[$name] = $definition;
}
return $this->_components[$name] = Kiri::createObject($definition);
} else if ($throwException) {
throw new \Exception("Unknown component ID: $name");
}
return null;
}
/**
* @param array $components
*/
public function setComponents(array $components)
{
foreach ($components as $name => $component) {
$this->set($name, $component);
}
}
/**
* @param $id
* @return bool
*/
public function has($id): bool
{
return isset($this->_components[$id]) || isset($this->_definition[$id]);
}
/**
* @param $id
*/
public function remove($id): void
{
unset($this->_components[$id], $this->_definition[$id]);
}
}
-289
View File
@@ -1,289 +0,0 @@
<?php
namespace Kiri\Di;
use JetBrains\PhpStorm\Pure;
use ReflectionAttribute;
use ReflectionClass;
use ReflectionProperty;
class NoteManager
{
private static array $_classTarget = [];
private static array $_classMethodNote = [];
private static array $_classMethod = [];
private static array $_classPropertyNote = [];
private static array $_classProperty = [];
private static array $_mapping = [];
/**
* @param ReflectionClass $class
*/
public static function setTargetNote(ReflectionClass $class)
{
$className = $class->getName();
if (!isset(static::$_classTarget[$className])) {
static::$_classTarget[$className] = [];
}
foreach ($class->getAttributes() as $attribute) {
if (!class_exists($attribute->getName())) {
continue;
}
$instance = $attribute->newInstance();
static::$_classTarget[$className][] = $instance;
self::setMappingClass($attribute, $className);
}
}
/**
* @param ReflectionAttribute $attribute
* @param string $class
*/
public static function setMappingClass(ReflectionAttribute $attribute, string $class)
{
if (!isset(static::$_mapping[$attribute->getName()])) {
static::$_mapping[$attribute->getName()] = [];
}
if (!isset(static::$_mapping[$attribute->getName()][$class])) {
static::$_mapping[$attribute->getName()][$class] = [];
}
}
/**
* @param ReflectionAttribute $attribute
* @param string $class
* @param string $method
* @param mixed $instance
*/
public static function setMappingMethod(ReflectionAttribute $attribute, string $class, string $method, mixed $instance)
{
self::setMappingClass($attribute, $class);
if (!isset(static::$_mapping[$attribute->getName()][$class]['method'])) {
static::$_mapping[$attribute->getName()][$class]['method'] = [];
}
static::$_mapping[$attribute->getName()][$class]['method'][] = [$method => $instance];
}
/**
* @param ReflectionAttribute $attribute
* @param string $class
* @param string $property
* @param $instance
*/
public static function setMappingProperty(ReflectionAttribute $attribute, string $class, string $property, $instance)
{
self::setMappingClass($attribute, $class);
$mapping = static::$_mapping[$attribute->getName()][$class];
if (!isset($mapping['property'])) {
$mapping['property'] = [];
}
$mapping['property'][] = [$property => $instance];
static::$_mapping[$attribute->getName()][$class] = $mapping;
}
/**
* @param mixed $class
* @return array
*/
public static function getTargetNote(mixed $class): array
{
if (!is_string($class)) {
$class = $class::class;
}
return static::$_classTarget[$class] ?? [];
}
/**
* @param ReflectionClass $class
*/
public static function setMethodNote(ReflectionClass $class)
{
$className = $class->getName();
static::$_classMethodNote[$className] = static::$_classMethod[$className] = [];
foreach ($class->getMethods() as $ReflectionMethod) {
static::$_classMethod[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
static::$_classMethodNote[$className][$ReflectionMethod->getName()] = [];
foreach ($ReflectionMethod->getAttributes() as $attribute) {
if (!class_exists($attribute->getName())) {
continue;
}
$instance = $attribute->newInstance();
static::$_classMethodNote[$className][$ReflectionMethod->getName()][] = $instance;
self::setMappingMethod($attribute, $className, $ReflectionMethod->getName(), $instance);
}
}
}
/**
* @param string $class
* @param string $method
* @return bool
*/
public static function hasMethod(string $class, string $method): bool
{
return isset(static::$_classMethod[$class]) && isset(static::$_classMethod[$class][$method]);
}
/**
* @param ReflectionClass $class
* @return array
*/
#[Pure] public static function getMethodNote(ReflectionClass $class): array
{
return static::$_classMethodNote[$class->getName()] ?? [];
}
/**
* @param \ReflectionClass $reflect
* @return \ReflectionMethod|null
*/
public static function resolveTarget(ReflectionClass $reflect): ?\ReflectionMethod
{
NoteManager::setPropertyNote($reflect);
NoteManager::setTargetNote($reflect);
NoteManager::setMethodNote($reflect);
return $reflect->getConstructor();
}
/**
* @param ReflectionClass $class
*/
public static function setPropertyNote(ReflectionClass $class)
{
$className = $class->getName();
static::$_classProperty[$className] = static::$_classPropertyNote[$className] = [];
foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PUBLIC |
ReflectionProperty::IS_PROTECTED) as $ReflectionMethod) {
static::$_classProperty[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
foreach ($ReflectionMethod->getAttributes() as $attribute) {
if (!class_exists($attribute->getName())) {
continue;
}
$instance = $attribute->newInstance();
static::$_classPropertyNote[$className][$ReflectionMethod->getName()] = $instance;
self::setMappingProperty($attribute, $className, $ReflectionMethod->getName(), $instance);
}
}
}
/**
* @param string $attribute
* @param string|null $class
* @return array[]
*/
public static function getAttributeTrees(string $attribute, string $class = null): array
{
$mapping = static::$_mapping[$attribute] ?? [];
if (empty($mapping) || empty($class)) {
return $mapping;
}
return $mapping[$class] ?? [];
}
/**
* @param string $attribute
* @param string $class
* @param string|null $method
* @return array
*/
public static function getSpecify_annotation(string $attribute, string $class, string $method = null): mixed
{
$class = self::getAttributeTrees($attribute, $class);
if (empty($class) || !isset($class['method'])){
return null;
}
if (empty($method)) {
return $class['method'];
}
foreach ($class['method'] as $value) {
$key = key($value);
if ($method == $key) {
return $value[$key];
}
}
return null;
}
/**
* @param string $attribute
* @param string $class
* @param string $method
* @return mixed
*/
public static function getPropertyByAnnotation(string $attribute, string $class, string $method): mixed
{
$class = self::getAttributeTrees($attribute, $class);
if (empty($class) || !isset($class['property'])) {
return [];
}
foreach ($class['property'] as $value) {
$key = key($value);
if ($method == $key) {
return $value[$key];
}
}
return null;
}
/**
* @param ReflectionClass|string $class
* @return array
* @throws \ReflectionException
*/
public static function getMethods(ReflectionClass|string $class): array
{
if (is_string($class)) {
$class = self::getReflect($class);
}
return static::$_classMethod[$class->getName()] ?? [];
}
/**
* @param ReflectionClass $class
* @return ReflectionProperty[]
*/
#[Pure] public static function getProperty(ReflectionClass $class): array
{
return static::$_classProperty[$class->getName()] ?? [];
}
/**
* @param ReflectionClass $class
* @return array
*/
#[Pure] public static function getPropertyNote(ReflectionClass $class): array
{
return static::$_classPropertyNote[$class->getName()] ?? [];
}
}
+46 -46
View File
@@ -1,46 +1,46 @@
<?php <?php
namespace Kiri; namespace Kiri;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Kiri;
/** /**
* Class Environmental * Class Environmental
* @package Kiri * @package Kiri
*/ */
class Environmental class Environmental
{ {
/** /**
* @return bool * @return bool
*/ */
public function isMac(): bool public function isMac(): bool
{ {
$output = strtolower(PHP_OS | PHP_OS_FAMILY); $output = strtolower(PHP_OS | PHP_OS_FAMILY);
if (str_contains('mac', $output)) { if (str_contains('mac', $output)) {
return true; return true;
} else if (str_contains('darwin', $output)) { } else if (str_contains('darwin', $output)) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
/** /**
* @return bool * @return bool
*/ */
#[Pure] public function isLinux(): bool #[Pure] public function isLinux(): bool
{ {
if (!static::isMac()) { if (!static::isMac()) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
} }
+151 -158
View File
@@ -1,158 +1,151 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/26 0026 * Date: 2018/4/26 0026
* Time: 10:00 * Time: 10:00
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
use Http\Handler\Formatter\IFormatter; use Kiri\Message\Handler\Formatter\IFormatter;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Core\Json; use Kiri\Core\Json;
use Kiri\Events\EventDispatch; use Kiri\Events\EventDispatch;
use Kiri\Kiri; use Kiri;
use Http\Events\OnAfterRequest; use Kiri\Message\Events\OnAfterRequest;
/** /**
* Class ErrorHandler * Class ErrorHandler
* *
* @package Kiri\Kiri\Base * @package Kiri\Base
* @property-read $asError * @property-read $asError
*/ */
class ErrorHandler extends Component implements ErrorInterface class ErrorHandler extends Component implements ErrorInterface
{ {
/** @var ?IFormatter $message */ /** @var ?IFormatter $message */
private ?IFormatter $message = NULL; private ?IFormatter $message = NULL;
public string $category = 'app'; public string $category = 'app';
/** /**
* 错误处理注册 * 错误处理注册
*/ */
public function register() public function register()
{ {
// ini_set('display_errors', '1'); set_exception_handler([$this, 'exceptionHandler']);
set_exception_handler([$this, 'exceptionHandler']); set_error_handler([$this, 'errorHandler']);
if (defined('HHVM_VERSION')) { register_shutdown_function([$this, 'shutdown']);
set_error_handler([$this, 'errorHandler']); }
} else {
set_error_handler([$this, 'errorHandler']); /**
} * @throws Exception
register_shutdown_function([$this, 'shutdown']); */
} public function shutdown()
{
/** $lastError = error_get_last();
* @throws Exception if (empty($lastError) || $lastError['type'] !== E_ERROR) {
*/ return;
public function shutdown() }
{
$lastError = error_get_last(); $this->category = 'shutdown';
if (empty($lastError) || $lastError['type'] !== E_ERROR) {
return; $messages = explode(PHP_EOL, $lastError['message']);
}
$message = array_shift($messages);
$this->category = 'shutdown';
$this->sendError($message, $lastError['file'], $lastError['line']);
$messages = explode(PHP_EOL, $lastError['message']); }
$message = array_shift($messages);
/**
$this->sendError($message, $lastError['file'], $lastError['line']); * @param \Throwable $exception
} *
* @throws Exception
*/
/** public function exceptionHandler(\Throwable $exception)
* @param \Throwable $exception {
* $this->category = 'exception';
* @throws Exception
*/ di(EventDispatch::class)->dispatch(new OnAfterRequest());
public function exceptionHandler(\Throwable $exception)
{ $this->sendError($exception->getMessage(), $exception->getFile(), $exception->getLine());
$this->category = 'exception'; }
di(EventDispatch::class)->dispatch(new OnAfterRequest());
/**
$this->sendError($exception->getMessage(), $exception->getFile(), $exception->getLine()); * @throws Exception
} *
* 以异常形式抛出错误,防止执行后续程序
*/
/** public function errorHandler()
* @throws Exception {
* $error = func_get_args();
* 以异常形式抛出错误,防止执行后续程序
*/ $path = ['file' => $error[2], 'line' => $error[3]];
public function errorHandler()
{ if ($error[0] === 0) {
$error = func_get_args(); $error[0] = 500;
}
$path = ['file' => $error[2], 'line' => $error[3]];
$data = Json::to(500, $error[1], $path);
if ($error[0] === 0) {
$error[0] = 500; Kiri::app()->error($data, 'error');
}
di(EventDispatch::class)->dispatch(new OnAfterRequest());
$data = Json::to(500, $error[1], $path);
Kiri::app()->error($data, 'error'); throw new \ErrorException($error[1], $error[0], 1, $error[2], $error[3]);
}
di(EventDispatch::class)->dispatch(new OnAfterRequest());
/**
* @param $message
throw new \ErrorException($error[1], $error[0], 1, $error[2], $error[3]); * @param $file
} * @param $line
* @param int $code
/** * @return false|string
* @param $message * @throws Exception
* @param $file */
* @param $line public function sendError($message, $file, $line, $code = 500): bool|string
* @param int $code {
* @return false|string $path = ['file' => $file, 'line' => $line];
* @throws Exception
*/ $data = Json::to($code, $this->category . ': ' . $message, $path);
public function sendError($message, $file, $line, $code = 500): bool|string
{ write($data, $this->category);
$path = ['file' => $file, 'line' => $line];
return $data;
var_dump(func_get_args()); }
$data = Json::to($code, $this->category . ': ' . $message, $path); /**
* @return mixed
write($data, $this->category); */
public function getErrorMessage(): mixed
return $data; {
} $message = $this->message;
$this->message = NULL;
/** return $message->getData();
* @return mixed }
*/
public function getErrorMessage(): mixed /**
{ * @return bool
$message = $this->message; */
$this->message = NULL; public function getAsError(): bool
return $message->getData(); {
} return $this->message !== NULL;
}
/**
* @return bool /**
*/ * @param $message
public function getAsError(): bool * @param string $category
{ *
return $this->message !== NULL; * @throws Exception
} */
public function writer($message, string $category = 'app')
/** {
* @param $message Kiri::app()->debug($message, $category);
* @param string $category }
* }
* @throws Exception
*/
public function writer($message, string $category = 'app')
{
Kiri::app()->debug($message, $category);
}
}
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-20 * Date: 2019-03-20
* Time: 10:25 * Time: 10:25
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Error; namespace Kiri\Error;
/** /**
* Interface ErrorInterface * Interface ErrorInterface
* @package Kiri\Kiri\Error * @package Kiri\Error
*/ */
interface ErrorInterface interface ErrorInterface
{ {
/** /**
* @param $message * @param $message
* @param $file * @param $file
* @param $line * @param $line
* @param int $code * @param int $code
* @return mixed * @return mixed
*/ */
public function sendError($message, $file, $line, $code = 500): mixed; public function sendError($message, $file, $line, $code = 500): mixed;
} }
+117 -111
View File
@@ -1,111 +1,117 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-22 * Date: 2019-03-22
* Time: 14:36 * Time: 14:36
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Error; namespace Kiri\Error;
use Annotation\Inject; use Exception;
use Exception; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Component; use Kiri\Core\Json;
use Kiri\Core\Json; use Kiri;
use Kiri\Events\EventProvider; use Kiri\Annotation\Inject;
use Kiri\Kiri; use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface; use Throwable;
use Throwable;
/**
/** * Class Logger
* Class Logger * @package Kiri\Error
* @package Kiri\Kiri\Error * @mixin \Kiri\Abstracts\Logger
* @mixin \Kiri\Abstracts\Logger */
*/ class Logger extends Component
class Logger extends Component {
{
private array $logs = [];
private array $logs = [];
/**
/** @var EventProvider */ * inject logger
#[Inject(EventProvider::class)] *
public EventProvider $eventProvider; * @var LoggerInterface
*/
#[Inject(LoggerInterface::class)]
/** public LoggerInterface $logger;
* inject logger
*
* @var LoggerInterface private array $sources = [];
*/
#[Inject(LoggerInterface::class)]
public LoggerInterface $logger; /**
* @param string $application
* @return string
private array $sources = []; */
public function getLastError(string $application = 'app'): string
{
/** return $this->logs[$application] ?? 'Unknown error.';
* @param string $application }
* @return string
*/
public function getLastError(string $application = 'app'): string /**
{ * @param $message
return 'Unknown error.'; * @param $method
} * @return void
*/
/** public function fail($message, $method)
* @param string $messages {
* @param string $method $this->logs[$method] = $message;
* @throws Exception }
*/
public function write(string $messages, string $method = 'app')
{ /**
if (empty($messages)) { * @param string $messages
return; * @param string $method
} * @throws Exception
*/
$to_day = date('Y-m-d'); public function write(string $messages, string $method = 'app')
{
$fileName = storage('server-' . $to_day . '.log', $dirName = 'log/' . ($method ?? 'app')); if (empty($messages)) {
return;
file_put_contents($fileName, '[' . date('Y-m-d H:i:s') . ']:' . PHP_EOL . $messages . PHP_EOL); }
}
$to_day = date('Y-m-d');
/** $fileName = storage('server-' . $to_day . '.log', $dirName = 'log/' . ($method ?? 'app'));
* @param Throwable $exception
* @return mixed file_put_contents($fileName, '[' . date('Y-m-d H:i:s') . ']:' . PHP_EOL . $messages . PHP_EOL);
* @throws Exception }
*/
public function exception(Throwable $exception): mixed
{ /**
$code = $exception->getCode() == 0 ? 500 : $exception->getCode(); * @param Throwable $exception
* @return mixed
$logger = Kiri::app()->getLogger(); * @throws Exception
$logger->write(jTraceEx($exception), 'exception'); */
public function exception(Throwable $exception): mixed
return Json::to($code, $exception->getMessage(), [ {
'file' => $exception->getFile(), $code = $exception->getCode() == 0 ? 500 : $exception->getCode();
'line' => $exception->getLine()
]); $logger = Kiri::app()->getLogger();
} $logger->write(jTraceEx($exception), 'exception');
return Json::to($code, $exception->getMessage(), [
/** 'file' => $exception->getFile(),
* @param string $name 'line' => $exception->getLine()
* @param array $arguments ]);
* @return mixed }
*/
public function __call(string $name, array $arguments): mixed
{ /**
if (!method_exists($this, $name)) { * @param string $name
return $this->logger->{$name}(...$arguments); * @param array $arguments
} else { * @return mixed
return $this->{$name}(...$arguments); */
} public function __call(string $name, array $arguments): mixed
} {
if (!method_exists($this, $name)) {
return $this->logger->{$name}(...$arguments);
} } else {
return $this->{$name}(...$arguments);
}
}
}
+53 -52
View File
@@ -1,52 +1,53 @@
<?php <?php
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
use Http\Aspect\OnAspectInterface; use Kiri\Message\Aspect\OnAspectInterface;
use Http\Aspect\OnJoinPointInterface; use Kiri\Message\Aspect\OnJoinPointInterface;
use Http\Constrict\RequestInterface; use Kiri\Message\Constrict\RequestInterface;
use Kiri\Kiri; use Kiri;
use Psr\Log\LoggerInterface;
/**
* Class LoggerAspect /**
* @package Kiri\Error * Class LoggerAspect
*/ * @package Kiri\Error
class LoggerAspect implements OnAspectInterface */
{ class LoggerAspect implements OnAspectInterface
{
/**
* @param OnJoinPointInterface $joinPoint /**
* @return mixed * @param OnJoinPointInterface $joinPoint
* @throws Exception * @return mixed
*/ * @throws Exception
public function process(OnJoinPointInterface $joinPoint): mixed */
{ public function process(OnJoinPointInterface $joinPoint): mixed
$time = microtime(true); {
$time = microtime(true);
$response = $joinPoint->process();
$response = $joinPoint->process();
$this->print_runtime($time);
$this->print_runtime($time);
return $response;
} return $response;
}
/**
* @param $startTime /**
* @throws Exception * @param $startTime
*/ * @throws Exception
private function print_runtime($startTime) */
{ private function print_runtime($startTime)
$request = Kiri::getDi()->get(RequestInterface::class); {
$request = Kiri::getDi()->get(RequestInterface::class);
$runTime = round(microtime(true) - $startTime, 6); $runTime = round(microtime(true) - $startTime, 6);
echo sprintf('run %s use time %6f', $request->getUri()->__toString(), $runTime);
echo PHP_EOL; $logger = Kiri::getDi()->get(LoggerInterface::class);
} $logger->debug(sprintf('run %s use time %6f', $request->getUri()->__toString(), $runTime));
}
}
}
+97 -83
View File
@@ -1,83 +1,97 @@
<?php <?php
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
use JetBrains\PhpStorm\Pure; use Kiri\Core\Json;
use Kiri\Core\Json; use Kiri\Exception\ComponentException;
use Kiri\Exception\ComponentException; use Kiri;
use Kiri\Kiri; use Kiri\Server\Abstracts\BaseProcess;
use Swoole\Coroutine; use Kiri\Server\Broadcast\OnBroadcastInterface;
use Swoole\Process; use Psr\Log\LoggerInterface;
use Server\Abstracts\BaseProcess; use Swoole\Coroutine;
use Swoole\Process;
/**
* Class LoggerProcess /**
* @package Kiri\Error * Class LoggerProcess
*/ * @package Kiri\Error
class LoggerProcess extends BaseProcess */
{ class LoggerProcess extends BaseProcess
{
public string $name = 'logger process';
public string $name = 'logger process';
/** /**
* @param Process $process * @param Process $process
* @throws ComponentException * @throws ComponentException
*/ */
public function process(Process $process): void public function process(Process $process): void
{ {
// TODO: Implement onHandler() method. // TODO: Implement onHandler() method.
$this->message($process); $this->message($process);
} }
/** /**
* @param Process $process * @param OnBroadcastInterface $message
* @throws ComponentException * @return void
* @throws Exception */
*/ public function onBroadcast(OnBroadcastInterface $message): void
public function message(Process $process) {
{ $logger = Kiri::getDi()->get(LoggerInterface::class);
$message = Json::decode($process->read()); $logger->debug($message->data . '::' . static::class);
if (!empty($message)) { }
Kiri::writeFile($this->getDirName($message), $message[0], FILE_APPEND);
$this->checkLogFile($message[1]); /**
} * @param Process $process
* @throws ComponentException
Coroutine\System::sleep(1); * @throws Exception
*/
$this->message($process); public function message(Process $process)
} {
if ($this->isStop()) {
return;
/** }
* @param $message $message = Json::decode($process->read());
* @return string if (!empty($message)) {
* @throws Exception Kiri::writeFile($this->getDirName($message), $message[0], FILE_APPEND);
*/
private function getDirName($message): string $this->checkLogFile($message[1]);
{ }
return storage('server-' . date('Y-m-d') . '.log', $message[1]);
} Coroutine\System::sleep(1);
$this->message($process);
/** }
* @param $dirName
* @throws Exception
*/ /**
private function checkLogFile($dirName) * @param $message
{ * @return string
$files = new \DirectoryIterator(storage(null, $dirName)); * @throws Exception
if ($files->getSize() < 15) { */
return; private function getDirName($message): string
} {
Coroutine\System::exec('find ' . storage(null, $dirName) . '/ -mtime +15 -name "*.log" -exec rm -rf {} \;'); return storage('server-' . date('Y-m-d') . '.log', $message[1]);
} }
}
/**
* @param $dirName
* @throws Exception
*/
private function checkLogFile($dirName)
{
$files = new \DirectoryIterator(storage(null, $dirName));
if ($files->getSize() < 15) {
return;
}
Coroutine\System::exec('find ' . storage(null, $dirName) . '/ -mtime +15 -name "*.log" -exec rm -rf {} \;');
}
}
+238 -239
View File
@@ -1,239 +1,238 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\BaseObject; use Kiri\Abstracts\Component;
use Swoole\Coroutine; use Kiri;
/**
/** * Class Event
* Class Event * @package Kiri
* @package Kiri */
*/ class Event extends Component
class Event extends BaseObject {
{
public bool $isVide = true;
public bool $isVide = true;
private static array $_events = [];
private static array $_events = [];
const PIPE_MESSAGE = 'SERVER:PIPE:MESSAGE';
const PIPE_MESSAGE = 'SERVER:PIPE:MESSAGE'; const TASK_FINISH = 'SERVER:TASK::FINISH';
const TASK_FINISH = 'SERVER:TASK::FINISH';
const EVENT_AFTER_REQUEST = 'SERVER:REQUEST:AFTER:START';
const EVENT_AFTER_REQUEST = 'SERVER:REQUEST:AFTER:START'; const EVENT_BEFORE_REQUEST = 'SERVER:REQUEST:BEFORE:START';
const EVENT_BEFORE_REQUEST = 'SERVER:REQUEST:BEFORE:START'; const RECEIVE_CONNECTION = 'SERVER:RECEIVE:CONNECTION';
const RECEIVE_CONNECTION = 'SERVER:RECEIVE:CONNECTION';
const SYSTEM_RESOURCE_RELEASES = 'SYSTEM::RESOURCE::RELEASES';
const SYSTEM_RESOURCE_RELEASES = 'SYSTEM::RESOURCE::RELEASES'; const SYSTEM_RESOURCE_CLEAN = 'SYSTEM::RESOURCE::CLEAN';
const SYSTEM_RESOURCE_CLEAN = 'SYSTEM::RESOURCE::CLEAN';
const PROCESS_WORKER_STOP = 'SERVER:PROCESS:WORKER:STOP';
const PROCESS_WORKER_STOP = 'SERVER:PROCESS:WORKER:STOP';
const SERVER_AFTER_RELOAD = 'SERVER:AFTER:RELOAD';
const SERVER_AFTER_RELOAD = 'SERVER:AFTER:RELOAD'; const SERVER_BEFORE_RELOAD = 'SERVER:BEFORE:RELOAD';
const SERVER_BEFORE_RELOAD = 'SERVER:BEFORE:RELOAD'; const SERVER_CONNECT = 'SERVER:CONNECT';
const SERVER_CONNECT = 'SERVER:CONNECT'; const SERVER_PACKAGE = 'SERVER:PACKAGE';
const SERVER_PACKAGE = 'SERVER:PACKAGE'; const SERVER_RECEIVE = 'SERVER:RECEIVE';
const SERVER_RECEIVE = 'SERVER:RECEIVE';
const SERVER_EVENT_START = 'SERVER:EVENT:START';
const SERVER_EVENT_START = 'SERVER:EVENT:START'; const SERVER_MANAGER_START = 'SERVER:EVENT:MANAGER:START';
const SERVER_MANAGER_START = 'SERVER:EVENT:MANAGER:START'; const SERVER_MANAGER_STOP = 'SERVER:EVENT:MANAGER:START';
const SERVER_MANAGER_STOP = 'SERVER:EVENT:MANAGER:START'; const SERVER_WORKER_STOP = 'SERVER:EVENT:WORKER:STOP';
const SERVER_WORKER_STOP = 'SERVER:EVENT:WORKER:STOP'; const SERVER_WORKER_START = 'SERVER:EVENT:WORKER:START';
const SERVER_WORKER_START = 'SERVER:EVENT:WORKER:START'; const SERVER_AFTER_WORKER_START = 'SERVER:EVENT:AFTER:WORKER:START';
const SERVER_AFTER_WORKER_START = 'SERVER:EVENT:AFTER:WORKER:START'; const SERVER_BEFORE_START = 'SERVER:EVENT:BEFORE:START';
const SERVER_BEFORE_START = 'SERVER:EVENT:BEFORE:START'; const BEFORE_COMMAND_EXECUTE = 'COMMAND:EVENT:BEFORE:EXECUTE';
const BEFORE_COMMAND_EXECUTE = 'COMMAND:EVENT:BEFORE:EXECUTE'; const AFTER_COMMAND_EXECUTE = 'COMMAND:EVENT:AFTER:EXECUTE';
const AFTER_COMMAND_EXECUTE = 'COMMAND:EVENT:AFTER:EXECUTE'; const SERVER_TASK_START = 'SERVER:EVENT:TASK:START';
const SERVER_TASK_START = 'SERVER:EVENT:TASK:START'; const SERVER_WORKER_EXIT = 'SERVER:EVENT:WORKER:EXIT';
const SERVER_WORKER_EXIT = 'SERVER:EVENT:WORKER:EXIT'; const SERVER_WORKER_ERROR = 'SERVER:EVENT:WORKER:ERROR';
const SERVER_WORKER_ERROR = 'SERVER:EVENT:WORKER:ERROR'; const SERVER_SHUTDOWN = 'SERVER:EVENT:SHUTDOWN';
const SERVER_SHUTDOWN = 'SERVER:EVENT:SHUTDOWN';
const SERVER_HANDSHAKE = 'on handshake';
const SERVER_HANDSHAKE = 'on handshake'; const SERVER_MESSAGE = 'on message';
const SERVER_MESSAGE = 'on message'; const SERVER_CLIENT_CLOSE = 'SERVER:CLIENT:CLOSE';
const SERVER_CLIENT_CLOSE = 'SERVER:CLIENT:CLOSE';
const SERVER_ON_START = 'Start';
const SERVER_ON_START = 'Start'; const SERVER_ON_SHUTDOWN = 'Shutdown';
const SERVER_ON_SHUTDOWN = 'Shutdown'; const SERVER_ON_WORKER_START = 'WorkerStart';
const SERVER_ON_WORKER_START = 'WorkerStart'; const SERVER_ON_WORKER_STOP = 'WorkerStop';
const SERVER_ON_WORKER_STOP = 'WorkerStop'; const SERVER_ON_WORKER_EXIT = 'WorkerExit';
const SERVER_ON_WORKER_EXIT = 'WorkerExit'; const SERVER_ON_CONNECT = 'Connect';
const SERVER_ON_CONNECT = 'Connect'; const SERVER_ON_RECEIVE = 'Receive';
const SERVER_ON_RECEIVE = 'Receive'; const SERVER_ON_PACKET = 'Packet';
const SERVER_ON_PACKET = 'Packet'; const SERVER_ON_REQUEST = 'request';
const SERVER_ON_REQUEST = 'request'; const SERVER_ON_CLOSE = 'Close';
const SERVER_ON_CLOSE = 'Close'; const SERVER_ON_TASK = 'Task';
const SERVER_ON_TASK = 'Task'; const SERVER_ON_FINISH = 'Finish';
const SERVER_ON_FINISH = 'Finish'; const SERVER_ON_PIPE_MESSAGE = 'OnPipeMessageInterface';
const SERVER_ON_PIPE_MESSAGE = 'OnPipeMessageInterface'; const SERVER_ON_WORKER_ERROR = 'WorkerError';
const SERVER_ON_WORKER_ERROR = 'WorkerError'; const SERVER_ON_MANAGER_START = 'ManagerStart';
const SERVER_ON_MANAGER_START = 'ManagerStart'; const SERVER_ON_MANAGER_STOP = 'ManagerStop';
const SERVER_ON_MANAGER_STOP = 'ManagerStop'; const SERVER_ON_BEFORE_RELOAD = 'BeforeReload';
const SERVER_ON_BEFORE_RELOAD = 'BeforeReload'; const SERVER_ON_AFTER_RELOAD = 'AfterReload';
const SERVER_ON_AFTER_RELOAD = 'AfterReload';
/**
/** * @param $name
* @param $name * @param $callback
* @param $callback * @param bool $isAppend
* @param bool $isAppend * @throws Exception
* @throws Exception */
*/ public static function on($name, $callback, bool $isAppend = false)
public static function on($name, $callback, bool $isAppend = false) {
{ if (!isset(static::$_events[$name])) {
if (!isset(static::$_events[$name])) { static::$_events[$name] = [];
static::$_events[$name] = []; }
} if (is_array($callback) && is_string($callback[0])) {
if (is_array($callback) && is_string($callback[0])) { if (!class_exists($callback[0])) {
if (!class_exists($callback[0])) { throw new Exception('Undefined callback class.');
throw new Exception('Undefined callback class.'); }
} $callback[0] = di($callback[0]);
$callback[0] = di($callback[0]); }
} if (static::exists($name, $callback)) {
if (static::exists($name, $callback)) { return;
return; }
} if (!empty(static::$_events[$name]) && $isAppend === true) {
if (!empty(static::$_events[$name]) && $isAppend === true) { array_unshift(static::$_events[$name], [$callback]);
array_unshift(static::$_events[$name], [$callback]); } else {
} else { static::$_events[$name][] = [$callback];
static::$_events[$name][] = [$callback]; }
} }
}
/**
/** * @param $name
* @param $name * @param $callback
* @param $callback */
*/ public static function of($name, $callback): void
public static function of($name, $callback): void {
{ if (!isset(static::$_events[$name])) {
if (!isset(static::$_events[$name])) { return;
return; }
} foreach (static::$_events[$name] as $index => $event) {
foreach (static::$_events[$name] as $index => $event) { [$handler] = $event;
[$handler] = $event; if ($handler !== $callback) {
if ($handler !== $callback) { continue;
continue; }
} unset(static::$_events[$name][$index]);
unset(static::$_events[$name][$index]); }
} }
}
/**
/** * @param $name
* @param $name */
*/ public static function offName($name): void
public static function offName($name): void {
{ unset(static::$_events[$name]);
unset(static::$_events[$name]); }
}
/**
/** * @param $name
* @param $name * @param null $callback
* @param null $callback * @return bool
* @return bool */
*/ public static function exists($name, $callback): bool
public static function exists($name, $callback): bool {
{ if ($callback instanceof \Closure || !isset(static::$_events[$name])) {
if ($callback instanceof \Closure || !isset(static::$_events[$name])) { return false;
return false; }
} foreach (static::$_events[$name] as $event) {
foreach (static::$_events[$name] as $event) { [$handler] = $event;
[$handler] = $event; if ($handler === $callback) {
if ($handler === $callback) { return true;
return true; }
} }
} return false;
return false; }
}
/**
/** * @param $name
* @param $name * @param $handler
* @param $handler * @return mixed
* @return mixed */
*/ public static function get($name, $handler): mixed
public static function get($name, $handler): mixed {
{ if (!static::exists($name, $handler)) {
if (!static::exists($name, $handler)) { return null;
return null; }
} if (empty($handler)) {
if (empty($handler)) { return static::$_events[$name];
return static::$_events[$name]; }
} foreach (static::$_events[$name] as $event) {
foreach (static::$_events[$name] as $event) { [$callback] = $event;
[$callback] = $event; if ($callback === $handler) {
if ($callback === $handler) { return [$event];
return [$event]; }
} }
} return null;
return null; }
}
public static function clean()
public static function clean() {
{ static::$_events = [];
static::$_events = []; }
}
/**
/** * @param $name
* @param $name * @param array $params
* @param array $params * @return bool
* @return bool * @throws Exception
* @throws Exception */
*/ public function dispatch($name, array $params = []): bool
public function dispatch($name, array $params = []): bool {
{ return static::trigger($name, $params);
return static::trigger($name, $params); }
}
/**
/** * @param $name
* @param $name * @param null $parameter
* @param null $parameter * @param false $is_remove
* @param false $is_remove * @return bool
* @return bool * @throws Exception
* @throws Exception */
*/ public static function trigger($name, $parameter = null, bool $is_remove = false): bool
public static function trigger($name, $parameter = null, bool $is_remove = false): bool {
{ foreach ((static::$_events[$name] ?? []) as $key => $event) {
foreach ((static::$_events[$name] ?? []) as $key => $event) { static::execute($event, $parameter);
static::execute($event, $parameter); if ($event instanceof \Closure) {
if ($event instanceof \Closure) { unset(static::$_events[$name][$key]);
unset(static::$_events[$name][$key]); }
} }
} if ($is_remove) {
if ($is_remove) { unset(static::$_events[$name]);
unset(static::$_events[$name]); }
} return true;
return true; }
}
/**
/** * @param $event
* @param $event * @param $parameter
* @param $parameter * @return void
* @return void * @throws Exception
* @throws Exception */
*/ private static function execute($event, $parameter): void
private static function execute($event, $parameter): void {
{ try {
try { call_user_func($event[0], ...$parameter);
call_user_func($event[0], ...$parameter); } catch (\Throwable $throwable) {
} catch (\Throwable $throwable) { logger()->addError($throwable, 'throwable');
logger()->addError($throwable, 'throwable'); return;
return; }
} }
}
}
}
+16 -16
View File
@@ -1,16 +1,16 @@
<?php <?php
namespace Kiri\Events; namespace Kiri\Events;
class OnAfterCommandExecute class OnAfterCommandExecute
{ {
/** /**
* *
*/ */
public function __construct() public function __construct()
{ {
} }
} }
@@ -1,8 +1,8 @@
<?php <?php
namespace Kiri\Events; namespace Kiri\Events;
class OnBeforeCommandExecute class OnBeforeCommandExecute
{ {
} }
+29 -29
View File
@@ -1,29 +1,29 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use Throwable; use Throwable;
/** /**
* Class AuthException * Class AuthException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class AuthException extends \Exception class AuthException extends \Exception
{ {
/** /**
* AuthException constructor. * AuthException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
public function __construct($message = "", $code = 0, Throwable $previous = null) public function __construct($message = "", $code = 0, Throwable $previous = null)
{ {
parent::__construct($message, 4001, $previous); parent::__construct($message, 4001, $previous);
} }
} }
+35 -35
View File
@@ -1,35 +1,35 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/25 0025 * Date: 2018/4/25 0025
* Time: 18:34 * Time: 18:34
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use Throwable; use Throwable;
/** /**
* Class ComponentException * Class ComponentException
* @package Kiri\Kiri\Exception * @package Kiri\Exception
*/ */
class ComponentException extends \Exception class ComponentException extends \Exception
{ {
/** /**
* ComponentException constructor. * ComponentException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
public function __construct(string $message = "", int $code = 0, Throwable $previous = NULL) public function __construct(string $message = "", int $code = 0, Throwable $previous = NULL)
{ {
parent::__construct($message, 5000, $previous); parent::__construct($message, 5000, $previous);
} }
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
/** /**
* Class ConfigException * Class ConfigException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class ConfigException extends \Exception class ConfigException extends \Exception
{ {
} }
+14 -14
View File
@@ -1,14 +1,14 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
/** /**
* Class InitException * Class InitException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class InitException extends \Exception class InitException extends \Exception
{ {
} }
+36 -36
View File
@@ -1,36 +1,36 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/24 0024 * Date: 2018/4/24 0024
* Time: 17:32 * Time: 17:32
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Throwable; use Throwable;
/** /**
* Class NotFindClassException * Class NotFindClassException
* @package Kiri\Kiri\Exception * @package Kiri\Exception
*/ */
class NotFindClassException extends \Exception class NotFindClassException extends \Exception
{ {
/** /**
* NotFindClassException constructor. * NotFindClassException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
#[Pure] public function __construct(string $message = "", int $code = 0, Throwable $previous = null) #[Pure] public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
{ {
$message = "No class named `$message` was found, please check if the class name is correct"; $message = "No class named `$message` was found, please check if the class name is correct";
parent::__construct($message, 404, $previous); parent::__construct($message, 404, $previous);
} }
} }
@@ -1,35 +1,35 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/24 0024 * Date: 2018/4/24 0024
* Time: 17:32 * Time: 17:32
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use Throwable; use Throwable;
/** /**
* Class NotFindClassException * Class NotFindClassException
* @package Kiri\Kiri\Exception * @package Kiri\Exception
*/ */
class NotFindPropertyException extends \Exception class NotFindPropertyException extends \Exception
{ {
/** /**
* NotFindClassException constructor. * NotFindClassException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
public function __construct(string $message = "", int $code = 0, Throwable $previous = null) public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
{ {
$message = "No class named `$message` was found, please check if the class name is correct"; $message = "No class named `$message` was found, please check if the class name is correct";
parent::__construct($message, 404, $previous); parent::__construct($message, 404, $previous);
} }
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
/** /**
* Class RedisConnectException * Class RedisConnectException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class RedisConnectException extends \Exception class RedisConnectException extends \Exception
{ {
} }
+224 -154
View File
@@ -1,154 +1,224 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Annotation\Inject; use Exception;
use Exception; use Kiri;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Error\Logger; use Kiri\Annotation\Inject;
use Kiri\Exception\ConfigException; use Kiri\Core\Json;
use Kiri\Kiri; use Kiri\Error\Logger;
use Swoole\Coroutine; use Kiri\Exception\ConfigException;
use Swoole\Process; use Swoole\Coroutine;
use Symfony\Component\Console\Command\Command; use Swoole\Process;
use Symfony\Component\Console\Input\InputInterface; use Swoole\Timer;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
*
*/ /**
class HotReload extends Command *
{ */
class HotReload extends Command
{
public bool $isReloading = false;
public bool $isReloadingOut = false;
public ?array $dirs = []; public bool $isReloading = FALSE;
public bool $isReloadingOut = FALSE;
public int $events; public ?array $dirs = [];
public int $int = -1; public int $events;
public int $int = -1;
private ?Process $process = null;
private ?Process $process = NULL;
public Inotify|Scaner $driver;
public Inotify|Scaner $driver;
#[Inject(Logger::class)]
public Logger $logger;
#[Inject(Logger::class)]
public Logger $logger;
protected mixed $source = null;
protected mixed $pipes = []; protected mixed $source = NULL;
protected ?Coroutine\Channel $channel = null; protected mixed $pipes = [];
protected ?Coroutine\Channel $channel = NULL;
/**
*
*/ /**
protected function configure() */
{ protected function configure()
$this->setName('sw:wather') {
->setDescription('server start'); $this->setName('sw:wather')->setDescription('server start');
} }
/** /**
* @param InputInterface $input * @throws ConfigException
* @param OutputInterface $output * @throws Exception
* @return int */
* @throws ConfigException protected function initCore()
* @throws Exception {
*/ set_error_handler([$this, 'errorHandler']);
public function execute(InputInterface $input, OutputInterface $output): int $this->dirs = Config::get('inotify', [APP_PATH . 'app']);
{ if (!extension_loaded('inotify')) {
// TODO: Implement onHandler() method. $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]);
set_error_handler([$this, 'onErrorHandler']); } else {
$this->dirs = Config::get('inotify', [APP_PATH . 'app']); $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]);
swoole_async_set(['enable_coroutine' => false]); }
if (!extension_loaded('inotify')) { $this->clearOtherService();
$this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]); $this->setProcessName();
} else { }
$this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]);
}
if (Kiri::getPlatform()->isLinux()) { /**
swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather'); * @throws ConfigException
} */
$this->trigger_reload(); public function setProcessName()
{
var_dump(getmypid()); swoole_async_set(['enable_coroutine' => FALSE]);
Process::signal(SIGTERM, [$this, 'onSignal']); if (Kiri::getPlatform()->isLinux()) {
Process::signal(SIGKILL, [$this, 'onSignal']); swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather');
}
$this->driver->start(); }
return 0;
}
/**
* @throws Exception
/** */
* @param $data public function clearOtherService()
* @throws Exception {
*/ if (file_exists(storage('.manager.pid'))) {
public function onSignal($data) $pid = (int)file_get_contents(storage('.manager.pid'));
{ if ($pid > 0 && Process::kill($pid, 0)) {
if (!$data) { Process::kill($pid, 15) && Process::wait(TRUE);
return; }
} }
$this->driver->clear(); file_put_contents(storage('.manager.pid'), getmypid());
$pid = file_get_contents(storage('.swoole.pid')); }
if (!empty($pid) && Process::kill($pid, 0)) {
Process::kill($pid, SIGTERM);
} /**
if ($this->process && Process::kill($this->process->pid, 0)) { * @throws Exception
Process::kill($this->process->pid) && Process::wait(true); */
} public function errorHandler()
while ($ret = Process::wait(true)) { {
echo "PID={$ret['pid']}\n"; $error = func_get_args();
sleep(1);
} $path = ['file' => $error[2], 'line' => $error[3]];
}
if ($error[0] === 0) {
$error[0] = 500;
/** }
* @param $code $data = Json::to(500, $error[1], $path);
* @param $message
* @param $file $this->logger->error($data, 'error');
* @param $line }
* @throws Exception
*/
public function onErrorHandler($code, $message, $file, $line) /**
{ * @param InputInterface $input
if (str_contains($message, 'The file descriptor is not an inotify instance')) { * @param OutputInterface $output
return; * @return int
} * @throws ConfigException
debug('Error:' . $message . ' at ' . $file . ':' . $line); * @throws Exception
} */
public function execute(InputInterface $input, OutputInterface $output): int
{
/** $this->initCore();
* 重启
* $this->trigger_reload();
* @throws Exception Timer::tick(1000, fn() => $this->healthCheck());
*/
public function trigger_reload() Process::signal(SIGTERM, [$this, 'onSignal']);
{ Process::signal(SIGKILL, [$this, 'onSignal']);
$this->logger->warning('change reload');
$pid = $this->process?->pid; $this->driver->start();
$process = new Process(function (Process $process) { return 0;
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "restart"]); }
});
$process->start();
if ($pid && Process::kill($pid, 0)) { /**
Process::kill($pid) && Process::wait(true); * @throws Exception
} */
$this->process = null; public function healthCheck()
$this->process = $process; {
} $pid = (int)file_get_contents(storage('.swoole.pid'));
if ($this->int == 1) {
return;
} }
if (empty($pid)) {
$this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload();
} else if (!Process::kill($pid, 0)) {
$this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload();
}
}
/**
* @param $data
* @throws Exception
*/
public function onSignal($data)
{
if (!$data) {
return;
}
Timer::clearAll();
$this->driver->clear();
$this->stopServer();
while ($ret = Process::wait(TRUE)) {
echo "PID={$ret['pid']}\n";
sleep(1);
}
}
/**
* @throws Exception
*/
protected function stopServer()
{
$pid = file_get_contents(storage('.swoole.pid'));
if (!empty($pid) && Process::kill($pid, 0)) {
Process::kill($pid, SIGTERM);
}
if ($this->process && Process::kill($this->process->pid, 0)) {
Process::kill($this->process->pid) && Process::wait(TRUE);
}
}
/**
* 重启
*
* @throws Exception
*/
public function trigger_reload(string $path = '')
{
$this->logger->warning('change reload');
if (!empty($path) && str_starts_with($path, CONTROLLER_PATH)) {
$pid = file_get_contents(storage('.swoole.pid'));
if (!empty($pid) && Process::kill($pid, 0)) {
Process::kill($pid, SIGUSR1);
}
} else {
$this->int = 1;
$this->stopServer();
$this->process = new Process(function (Process $process) {
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "start"]);
});
$this->process->start();
$this->int = -1;
}
}
}
+171 -158
View File
@@ -1,158 +1,171 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
use Swoole\Event; use Swoole\Event;
use Swoole\Timer; use Swoole\Timer;
class Inotify class Inotify
{ {
private mixed $inotify; private mixed $inotify;
private mixed $events; private mixed $events;
private array $watchFiles = []; private array $watchFiles = [];
protected bool $isReloading = FALSE; public bool $isReloading = FALSE;
protected int $cid; protected int $cid;
const IG_DIR = [APP_PATH . 'commands', APP_PATH . '.git', APP_PATH . '.gitee']; const IG_DIR = [APP_PATH . 'commands', APP_PATH . '.git', APP_PATH . '.gitee'];
/** /**
* @param array $dirs * @param array $dirs
* @param HotReload $process * @param HotReload $process
*/ */
public function __construct(protected array $dirs, public HotReload $process) public function __construct(protected array $dirs, public HotReload $process)
{ {
} set_error_handler([$this, 'error']);
set_exception_handler([$this, 'error']);
}
/**
* @throws Exception
*/ /**
public function start() * @return void
{ */
$this->inotify = inotify_init(); public function error(): void
$this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; {
foreach ($this->dirs as $dir) {
if (!is_dir($dir)) continue; }
$this->watch($dir);
}
Event::add($this->inotify, [$this, 'check']); /**
Event::wait(); * @throws Exception
} */
public function start()
{
public function clear() $this->inotify = inotify_init();
{ $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE;
Event::del($this->inotify); foreach ($this->dirs as $dir) {
Event::exit(); if (!is_dir($dir)) continue;
} $this->watch($dir);
}
$this->process->int = -1;
/** Event::add($this->inotify, [$this, 'check']);
* 开始监听 Event::wait();
* @throws Exception }
*/
public function check()
{ public function clear()
if (!($events = inotify_read($this->inotify))) { {
return; Event::del($this->inotify);
} Event::exit();
if ($this->isReloading) { }
return;
}
/**
$LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM]; * 开始监听
foreach ($events as $ev) { * @throws Exception
if (!in_array($ev['mask'], $LISTEN_TYPE)) { */
continue; public function check()
} {
//非重启类型 if (!($events = inotify_read($this->inotify))) {
if (str_ends_with($ev['name'], '.php')) { return;
Timer::after(3000, fn()=>$this->reload()); }
$this->isReloading = TRUE; if ($this->isReloading) {
} return;
} }
}
$LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM];
/** foreach ($events as $ev) {
* @throws Exception if (!in_array($ev['mask'], $LISTEN_TYPE)) {
*/ continue;
public function reload() }
{
$this->process->trigger_reload(); $search = array_search($ev['wd'], $this->watchFiles);
$this->clearWatch();
foreach ($this->dirs as $root) { //非重启类型
$this->watch($root); if (str_ends_with($ev['name'], '.php')) {
}
$this->process->int = -1; Timer::after(3000, fn() => $this->reload($search));
$this->isReloading = FALSE; $this->isReloading = TRUE;
} }
}
}
/**
* @throws Exception /**
*/ * @throws Exception
public function clearWatch() */
{ public function reload($path)
foreach ($this->watchFiles as $wd) { {
try { $this->process->trigger_reload($path);
inotify_rm_watch($this->inotify, $wd); $this->process->int = -1;
} catch (\Throwable $exception) {
logger()->addError($exception, 'throwable'); $this->clearWatch();
} foreach ($this->dirs as $root) {
} $this->watch($root);
$this->watchFiles = []; }
} $this->isReloading = FALSE;
}
/**
* @param $dir /**
* @return bool * @throws Exception
* @throws Exception */
*/ public function clearWatch()
public function watch($dir): bool {
{ foreach ($this->watchFiles as $wd) {
//目录不存在 @inotify_rm_watch($this->inotify, $wd);
if (!is_dir($dir)) { }
return logger()->addError("[$dir] is not a directory."); $this->watchFiles = [];
} }
//避免重复监听
if (isset($this->watchFiles[$dir])) {
return FALSE; /**
} * @param $dir
* @return bool
if (in_array($dir, self::IG_DIR)) { * @throws Exception
return FALSE; */
} public function watch($dir): bool
{
$wd = @inotify_add_watch($this->inotify, $dir, $this->events); //目录不存在
$this->watchFiles[$dir] = $wd; if (!is_dir($dir)) {
return logger()->addError("[$dir] is not a directory.");
$files = scandir($dir); }
foreach ($files as $f) { //避免重复监听
if ($f == '.' || $f == '..') { if (isset($this->watchFiles[$dir])) {
continue; return FALSE;
} }
$path = $dir . '/' . $f;
//递归目录 if (in_array($dir, self::IG_DIR)) {
if (is_dir($path)) { return FALSE;
$this->watch($path); }
} else if (!str_ends_with($f, '.php')) {
continue; $wd = @inotify_add_watch($this->inotify, $dir, $this->events);
} $this->watchFiles[$dir] = $wd;
//检测文件类型
if (strstr($f, '.') == '.php') { $files = scandir($dir);
$wd = @inotify_add_watch($this->inotify, $path, $this->events); foreach ($files as $f) {
$this->watchFiles[$path] = $wd; if ($f == '.' || $f == '..') {
} continue;
} }
return TRUE; $path = $dir . '/' . $f;
} //递归目录
} if (is_dir($path)) {
$this->watch($path);
} else if (!str_ends_with($f, '.php')) {
continue;
}
//检测文件类型
if (strstr($f, '.') == '.php') {
$wd = @inotify_add_watch($this->inotify, $path, $this->events);
$this->watchFiles[$path] = $wd;
}
}
return TRUE;
}
}
+152 -147
View File
@@ -1,147 +1,152 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
class Scaner class Scaner
{ {
private array $md5Map = []; private array $md5Map = [];
/** public bool $isReloading = FALSE;
* @param array $dirs
* @param HotReload $process
*/ /**
public function __construct(protected array $dirs, public HotReload $process) * @param array $dirs
{ * @param HotReload $process
} */
public function __construct(protected array $dirs, public HotReload $process)
{
/** }
* @throws Exception
*/
public function start(): void /**
{ * @throws Exception
$this->loadDirs(); */
$this->tick(); public function start(): void
} {
$this->loadDirs();
$this->tick();
/** }
* @param bool $isReload
* @throws Exception
*/ /**
private function loadDirs(bool $isReload = false) * @param bool $isReload
{ * @throws Exception
foreach ($this->dirs as $value) { */
if (is_bool($path = realpath($value))) { private function loadDirs(bool $isReload = FALSE)
continue; {
} foreach ($this->dirs as $value) {
if (is_bool($path = realpath($value))) {
if (!is_dir($path)) continue; continue;
}
$this->loadByDir($path, $isReload);
} if (!is_dir($path)) continue;
}
$this->loadByDir($path, $isReload);
}
/** }
* @param $path
* @param bool $isReload
* @return void /**
* @throws Exception * @param $path
*/ * @param bool $isReload
private function loadByDir($path, bool $isReload = false): void * @return void
{ * @throws Exception
if (!is_string($path)) { */
return; private function loadByDir($path, bool $isReload = FALSE): void
} {
$path = rtrim($path, '/'); if (!is_string($path)) {
foreach (glob(realpath($path) . '/*') as $value) { return;
if (is_dir($value)) { }
$this->loadByDir($value, $isReload); $path = rtrim($path, '/');
} foreach (glob(realpath($path) . '/*') as $value) {
if (is_file($value)) { if (is_dir($value)) {
if ($this->checkFile($value, $isReload)) { $this->loadByDir($value, $isReload);
$this->timerReload(); }
break; if (is_file($value)) {
} if ($this->checkFile($value, $isReload)) {
} $this->isReloading = TRUE;
}
} sleep(2);
$this->timerReload($value);
/** break;
* @param $value }
* @param $isReload }
* @return bool }
*/ }
private function checkFile($value, $isReload): bool
{
$md5 = md5($value); /**
$mTime = filectime($value); * @param $value
if (!isset($this->md5Map[$md5])) { * @param $isReload
if ($isReload) { * @return bool
return true; */
} private function checkFile($value, $isReload): bool
$this->md5Map[$md5] = $mTime; {
} else { $md5 = md5($value);
if ($this->md5Map[$md5] != $mTime) { $mTime = filectime($value);
if ($isReload) { if (!isset($this->md5Map[$md5])) {
return true; if ($isReload) {
} return TRUE;
$this->md5Map[$md5] = $mTime; }
} $this->md5Map[$md5] = $mTime;
} } else {
return false; if ($this->md5Map[$md5] != $mTime) {
} if ($isReload) {
return TRUE;
}
/** $this->md5Map[$md5] = $mTime;
* @throws Exception }
*/ }
public function timerReload() return FALSE;
{ }
if ($this->process->isReloading) {
return;
} /**
$this->process->isReloading = true; * @throws Exception
$this->process->trigger_reload(); */
public function timerReload($path)
$this->process->int = -1; {
$this->isReloading = TRUE;
$this->loadDirs();
$this->process->trigger_reload($path);
$this->process->isReloading = FALSE;
$this->process->isReloadingOut = FALSE; $this->loadDirs();
$this->tick(); $this->process->int = -1;
}
$this->isReloading = FALSE;
$this->process->isReloadingOut = FALSE;
private bool $isStop = false;
$this->tick();
public function clear() }
{
$this->isStop = true;
} private bool $isStop = FALSE;
public function clear()
/** {
* @throws Exception $this->isStop = TRUE;
*/ }
public function tick()
{
if ($this->process->isReloading || $this->isStop) { /**
return; * @throws Exception
} */
public function tick()
$this->loadDirs(true); {
if ($this->isReloading || $this->isStop) {
sleep(2); return;
}
$this->tick();
} $this->loadDirs(TRUE);
} sleep(2);
$this->tick();
}
}
+27 -27
View File
@@ -1,27 +1,27 @@
<?php <?php
namespace Kiri; namespace Kiri;
interface IAspect interface IAspect
{ {
public function before(): void; public function before(): void;
/** /**
* @param mixed $response * @param mixed $response
*/ */
public function after(mixed $response): void; public function after(mixed $response): void;
/** /**
* @param mixed $handler * @param mixed $handler
* @param array $params * @param array $params
* @return mixed * @return mixed
*/ */
public function invoke(mixed $handler, array $params = []): mixed; public function invoke(mixed $handler, array $params = []): mixed;
} }
+13 -13
View File
@@ -1,13 +1,13 @@
<?php <?php
namespace Kiri; namespace Kiri;
interface IProxy interface IProxy
{ {
public function execute(); public function execute();
} }
+24 -24
View File
@@ -1,24 +1,24 @@
<?php <?php
namespace Kiri\Pool; namespace Kiri\Pool;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
trait Alias trait Alias
{ {
/** /**
* @param $cds * @param $cds
* @param false $isMaster * @param false $isMaster
* @return string * @return string
*/ */
#[Pure] public function name($cds, bool $isMaster = false): string #[Pure] public function name($cds, bool $isMaster = false): string
{ {
if ($isMaster === true) { if ($isMaster === true) {
return $cds . '_master'; return $cds . '_master';
} else { } else {
return $cds . '_slave'; return $cds . '_slave';
} }
} }
} }
+233 -219
View File
@@ -1,219 +1,233 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Pool; namespace Kiri\Pool;
use Closure; use Closure;
use Database\Mysql\PDO; use Database\Mysql\PDO;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Component;
use Kiri\Context; use Kiri\Abstracts\Config;
use Kiri\Kiri; use Kiri\Context;
use Swoole\Error; use Swoole\Error;
use Throwable; use Throwable;
/** /**
* Class Connection * Class Connection
* @package Kiri\Pool * @package Kiri\Pool
*/ */
class Connection extends Component class Connection extends Component
{ {
use Alias; use Alias;
/** /**
* @param $cds * @param $cds
* @return bool * @return bool
* *
* db is in transaction * db is in transaction
* @throws Exception * @throws Exception
*/ */
public function inTransaction($cds): bool public function inTransaction($cds): bool
{ {
$name = $this->name('Mysql:' . $cds, true); $name = $this->name('Mysql:' . $cds, true);
$connection = Context::getContext($name); $connection = Context::getContext($name);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
return $connection->inTransaction(); return $connection->inTransaction();
} }
return false; return false;
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @throws Exception * @throws Exception
*/ */
public function beginTransaction($coroutineName) public function beginTransaction($coroutineName)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, true); $coroutineName = $this->name('Mysql:' . $coroutineName, true);
$connection = Context::getContext($coroutineName); $connection = Context::getContext($coroutineName);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
$connection->beginTransaction(); $connection->beginTransaction();
} }
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @throws Exception * @throws Exception
*/ */
public function commit($coroutineName) public function commit($coroutineName)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, true); $coroutineName = $this->name('Mysql:' . $coroutineName, true);
$connection = Context::getContext($coroutineName); $connection = Context::getContext($coroutineName);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
$connection->commit(); $connection->commit();
} }
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @throws Exception * @throws Exception
*/ */
public function rollback($coroutineName) public function rollback($coroutineName)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, true); $coroutineName = $this->name('Mysql:' . $coroutineName, true);
$connection = Context::getContext($coroutineName); $connection = Context::getContext($coroutineName);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
$connection->rollBack(); $connection->rollBack();
} }
} }
/** /**
* @param mixed $config * @param mixed $config
* @param bool $isMaster * @param bool $isMaster
* @return PDO|null * @return PDO|null
* @throws Exception * @throws Exception
*/ */
public function get(mixed $config, bool $isMaster = false): ?PDO public function get(mixed $config, bool $isMaster = false): ?PDO
{ {
$coroutineName = $this->name('Mysql:' . $config['cds'], $isMaster); $coroutineName = $this->name('Mysql:' . $config['cds'], $isMaster);
if (($pdo = Context::getContext($coroutineName)) instanceof PDO) { if (($pdo = Context::getContext($coroutineName)) instanceof PDO) {
return $pdo; return $pdo;
} }
$minx = Config::get('databases.pool.min', 1); $minx = Config::get('databases.pool.min', 1);
/** @var PDO $connections */ /** @var PDO $connections */
$connections = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $minx); $connections = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $minx);
if (Context::hasContext('begin_' . $coroutineName)) { if (Context::hasContext('begin_' . $coroutineName)) {
$connections->beginTransaction(); $connections->beginTransaction();
} }
return Context::setContext($coroutineName, $connections); return Context::setContext($coroutineName, $connections);
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @param $config * @param $config
* @return Closure * @return Closure
*/ */
public function create($coroutineName, $config): Closure public function create($coroutineName, $config): Closure
{ {
return static function () use ($coroutineName, $config) { return static function () use ($coroutineName, $config) {
return Kiri::getDi()->create(PDO::class, [ return Kiri::getDi()->create(PDO::class, [$config]);
$config['database'], $config['cds'], $config['username'], $config['password'], $config['charset'] ?? 'utf8mb4' };
]); }
};
}
/**
* @param string $name
/** * @param PDO $PDO
* @param $name * @return void
* @param $isMaster * @throws Kiri\Exception\ConfigException
* @param $max * @throws Exception
* @throws Exception */
*/ public function addItem(string $name, PDO $PDO)
public function initConnections($name, $isMaster, $max) {
{ $this->getPool()->push($name, $PDO);
$this->getPool()->initConnections($name, $isMaster, $max); }
}
/**
/** * @param $name
* @param $coroutineName * @param $isMaster
* @param $isMaster * @param $max
* @throws Exception * @throws Exception
*/ */
public function release($coroutineName, $isMaster) public function initConnections($name, $isMaster, $max)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster); $pool = $this->getPool();
/** @var PDO $client */ $pool->initConnections($name, $isMaster, $max);
if (!($client = Context::getContext($coroutineName)) instanceof PDO) { }
return;
}
if ($client->inTransaction()) { /**
return; * @param $coroutineName
} * @param $isMaster
$this->getPool()->push($coroutineName, $client); * @param array $config
Context::remove($coroutineName); * @throws Kiri\Exception\ConfigException
} * @throws Exception
*/
public function release($coroutineName, $isMaster, array $config)
/** {
* @param $coroutineName $coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster);
* @return bool /** @var PDO $client */
*/ if (!($client = Context::getContext($coroutineName)) instanceof PDO) {
private function hasClient($coroutineName): bool $client = call_user_func($this->create($coroutineName, $config));
{ }
return Context::hasContext($coroutineName); if ($client->inTransaction()) {
} return;
}
$this->getPool()->push($coroutineName, $client);
/** Context::remove($coroutineName);
* batch release }
* @throws Exception
*/
public function connection_clear($name, $isMaster) /**
{ * @param $coroutineName
$this->getPool()->clean($this->name($name, $isMaster)); * @return bool
} */
private function hasClient($coroutineName): bool
{
/** return Context::hasContext($coroutineName);
* @param string $name }
* @param mixed $client
* @return bool
* @throws Exception /**
*/ * batch release
public function checkCanUse(string $name, mixed $client): bool * @throws Exception
{ */
try { public function connection_clear($name, $isMaster)
if (empty($client) || !($client instanceof PDO)) { {
$result = false; $this->getPool()->clean($this->name($name, $isMaster));
} else { }
$result = true;
}
} catch (Error | Throwable $exception) { /**
$result = $this->addError($exception, 'mysql'); * @param string $name
} finally { * @param mixed $client
return $result; * @return bool
} * @throws Exception
} */
public function checkCanUse(string $name, mixed $client): bool
{
/** try {
* @param $coroutineName if (empty($client) || !($client instanceof PDO)) {
* @param bool $isMaster $result = false;
* @throws Exception } else {
*/ $result = true;
public function disconnect($coroutineName, bool $isMaster = false) }
{ } catch (Error|Throwable $exception) {
Context::remove($coroutineName); $result = $this->addError($exception, 'mysql');
$coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster); } finally {
$this->getPool()->clean($coroutineName); return $result;
} }
}
/**
* @return Pool /**
* @throws Exception * @param $coroutineName
*/ * @param bool $isMaster
public function getPool(): Pool * @throws Exception
{ */
return Kiri::getDi()->get(Pool::class); public function disconnect($coroutineName, bool $isMaster = false)
} {
Context::remove($coroutineName);
} $coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster);
$this->getPool()->clean($coroutineName);
}
/**
* @return Pool
* @throws Exception
*/
public function getPool(): Pool
{
return Kiri::getDi()->get(Pool::class);
}
}
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
namespace Kiri\Pool\Helper; namespace Kiri\Pool\Helper;
interface QueueInterface interface QueueInterface
{ {
public function isEmpty(): bool; public function isEmpty(): bool;
public function push(mixed $data, float $timeout = -1): bool; public function push(mixed $data, float $timeout = -1): bool;
public function pop(float $timeout = -1): mixed; public function pop(float $timeout = -1): mixed;
public function stats(): array; public function stats(): array;
public function close(): bool; public function close(): bool;
public function length(): int; public function length(): int;
public function isFull(): bool; public function isFull(): bool;
} }
+101 -101
View File
@@ -1,101 +1,101 @@
<?php <?php
namespace Kiri\Pool\Helper; namespace Kiri\Pool\Helper;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
/** /**
* *
*/ */
class SplQueue implements QueueInterface class SplQueue implements QueueInterface
{ {
private \SplQueue $channel; private \SplQueue $channel;
public int $errCode = 0; public int $errCode = 0;
/** /**
* @param int $max * @param int $max
*/ */
#[Pure] public function __construct(public int $max) #[Pure] public function __construct(public int $max)
{ {
$this->channel = new \SplQueue(); $this->channel = new \SplQueue();
} }
/** /**
* @return bool * @return bool
*/ */
public function isEmpty(): bool public function isEmpty(): bool
{ {
// TODO: Implement isEmpty() method. // TODO: Implement isEmpty() method.
return $this->channel->count() < 1; return $this->channel->count() < 1;
} }
/** /**
* @param mixed $data * @param mixed $data
* @param float $timeout * @param float $timeout
* @return bool * @return bool
*/ */
public function push(mixed $data, float $timeout = -1): bool public function push(mixed $data, float $timeout = -1): bool
{ {
// TODO: Implement push() method. // TODO: Implement push() method.
$this->channel->enqueue($data); $this->channel->enqueue($data);
return true; return true;
} }
/** /**
* @param float $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public function pop(float $timeout = -1): mixed public function pop(float $timeout = -1): mixed
{ {
// TODO: Implement pop() method. // TODO: Implement pop() method.
return $this->channel->dequeue(); return $this->channel->dequeue();
} }
/** /**
* @return array * @return array
*/ */
public function stats(): array public function stats(): array
{ {
// TODO: Implement stats() method. // TODO: Implement stats() method.
return []; return [];
} }
/** /**
* @return bool * @return bool
*/ */
public function close(): bool public function close(): bool
{ {
// TODO: Implement close() method. // TODO: Implement close() method.
return false; return false;
} }
/** /**
* @return int * @return int
*/ */
public function length(): int public function length(): int
{ {
// TODO: Implement length() method. // TODO: Implement length() method.
return $this->channel->count(); return $this->channel->count();
} }
/** /**
* @return bool * @return bool
*/ */
public function isFull(): bool public function isFull(): bool
{ {
// TODO: Implement isFull() method. // TODO: Implement isFull() method.
return $this->channel->count() >= $this->max; return $this->channel->count() >= $this->max;
} }
} }
+248 -249
View File
@@ -1,249 +1,248 @@
<?php <?php
namespace Kiri\Pool; namespace Kiri\Pool;
use Exception; use Exception;
use Kiri\Context; use Kiri\Context;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Pool\Helper\SplQueue; use Kiri\Pool\Helper\SplQueue;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Coroutine\Channel; use Swoole\Coroutine\Channel;
/** /**
* Class Pool * Class Pool
* @package Kiri\Pool * @package Kiri\Pool
*/ */
class Pool extends Component class Pool extends Component
{ {
/** @var Channel[] */ /** @var Channel[] */
private static array $_connections = []; private static array $_connections = [];
public int $max = 60; public int $max = 60;
use Alias; use Alias;
/** /**
* @param $channel * @param $channel
* @param $retain_number * @param $retain_number
* @throws Exception * @throws Exception
*/ */
public function flush($channel, $retain_number) public function flush($channel, $retain_number)
{ {
$this->pop($channel, $retain_number); $this->pop($channel, $retain_number);
} }
/** /**
* @param Channel $channel * @param Channel|SplQueue $channel
* @param $retain_number * @param $retain_number
* @throws Exception */
*/ protected function pop(Channel|SplQueue $channel, $retain_number): void
protected function pop(Channel $channel, $retain_number): void {
{ while ($channel->length() > $retain_number) {
while ($channel->length() > $retain_number) { if (Context::inCoroutine()) {
if (Context::inCoroutine()) { $connection = $channel->pop();
$connection = $channel->pop(); if ($connection instanceof StopHeartbeatCheck) {
if ($connection instanceof StopHeartbeatCheck) { $connection->stopHeartbeatCheck();
$connection->stopHeartbeatCheck(); }
} }
} }
} }
}
/**
/** * @param $name
* @param $name * @param false $isMaster
* @param false $isMaster * @param int $max
* @param int $max * @throws ConfigException
* @throws ConfigException */
*/ public function initConnections($name, bool $isMaster = false, int $max = 60)
public function initConnections($name, bool $isMaster = false, int $max = 60) {
{ $name = $this->name($name, $isMaster);
$name = $this->name($name, $isMaster); if (isset(static::$_connections[$name])) {
if (isset(static::$_connections[$name])) { $value = static::$_connections[$name];
$value = static::$_connections[$name]; if ($value instanceof Channel || $value instanceof SplQueue) {
if ($value instanceof Channel || $value instanceof SplQueue) { return;
return; }
} }
} $this->newChannel($name, $max);
$this->newChannel($name, $max); $this->max = $max;
$this->max = $max; }
}
/**
/** * @param $name
* @param $name * @return Channel|SplQueue
* @return Channel|SplQueue * @throws ConfigException
* @throws ConfigException * @throws Exception
* @throws Exception */
*/ private function getChannel($name): Channel|SplQueue
private function getChannel($name): Channel|SplQueue {
{ if (!isset(static::$_connections[$name])) {
if (!isset(static::$_connections[$name])) { $this->newChannel($name);
$this->newChannel($name); }
} if (static::$_connections[$name]->errCode == SWOOLE_CHANNEL_CLOSED) {
if (static::$_connections[$name]->errCode == SWOOLE_CHANNEL_CLOSED) { throw new Exception('Channel is Close.');
throw new Exception('Channel is Close.'); }
} return static::$_connections[$name];
return static::$_connections[$name]; }
}
/**
/** * @throws ConfigException
* @throws ConfigException */
*/ private function newChannel($name, $max = null)
private function newChannel($name, $max = null) {
{ if ($max == null) {
if ($max == null) { $max = Config::get('databases.pool.max', 10);
$max = Config::get('databases.pool.max', 10); }
} if (Coroutine::getCid() === -1) {
if (Coroutine::getCid() === -1) { static::$_connections[$name] = new SplQueue($max);
static::$_connections[$name] = new SplQueue($max); } else {
} else { static::$_connections[$name] = new Channel($max);
static::$_connections[$name] = new Channel($max); }
} }
}
/**
/** * @param $name
* @param $name * @param $callback
* @param $callback * @param $minx
* @param $minx * @return array
* @return array * @throws ConfigException
* @throws ConfigException * @throws Exception
* @throws Exception */
*/ public function get($name, $callback, $minx): mixed
public function get($name, $callback, $minx): mixed {
{ $channel = $this->getChannel($name);
$channel = $this->getChannel($name); if (!$channel->isEmpty()) {
if (!$channel->isEmpty()) { return $this->maxIdleQuantity($channel, $minx);
return $this->maxIdleQuantity($channel, $minx); }
} return $callback();
return $callback(); }
}
/**
/** * @param $channel
* @param $channel * @param $minx
* @param $minx * @return mixed
* @return mixed * @throws Exception
* @throws Exception */
*/ protected function maxIdleQuantity($channel, $minx): mixed
protected function maxIdleQuantity($channel, $minx): mixed {
{ $connection = $channel->pop();
$connection = $channel->pop(); if ($channel->length() > $minx) {
if ($channel->length() > $minx) { $this->pop($channel, $minx);
$this->pop($channel, $minx); }
} return $connection;
return $connection; }
}
/**
/** * @param $name
* @param $name * @return bool
* @return bool * @throws ConfigException
* @throws ConfigException */
*/ public function isNull($name): bool
public function isNull($name): bool {
{ return $this->getChannel($name)->isEmpty();
return $this->getChannel($name)->isEmpty(); }
}
/**
/** * @param string $name
* @param string $name * @param mixed $client
* @param mixed $client * @return bool
* @return bool * 检查连接可靠性
* 检查连接可靠性 */
*/ public function checkCanUse(string $name, mixed $client): bool
public function checkCanUse(string $name, mixed $client): bool {
{ return true;
return true; }
}
/**
/** * @param string $name
* @param string $name * @return bool
* @return bool */
*/ public function hasItem(string $name): bool
public function hasItem(string $name): bool {
{ if (isset(static::$_connections[$name])) {
if (isset(static::$_connections[$name])) { return !static::$_connections[$name]->isEmpty();
return !static::$_connections[$name]->isEmpty(); }
} return false;
return false; }
}
/**
/** * @param string $name
* @param string $name * @return mixed
* @return mixed */
*/ public function size(string $name): mixed
public function size(string $name): mixed {
{ if (!isset(static::$_connections[$name])) {
if (!isset(static::$_connections[$name])) { return 0;
return 0; }
} return static::$_connections[$name]->length();
return static::$_connections[$name]->length(); }
}
/**
/** * @param string $name
* @param string $name * @param mixed $client
* @param mixed $client * @throws ConfigException
* @throws ConfigException */
*/ public function push(string $name, mixed $client)
public function push(string $name, mixed $client) {
{ $channel = $this->getChannel($name);
$channel = $this->getChannel($name); if (!$channel->isFull()) {
if (!$channel->isFull()) { $channel->push($client);
$channel->push($client); }
} unset($client);
unset($client); }
}
/**
/** * @param string $name
* @param string $name * @throws Exception
* @throws Exception */
*/ public function clean(string $name)
public function clean(string $name) {
{ if (!isset(static::$_connections[$name])) {
if (!isset(static::$_connections[$name])) { return;
return; }
} while (static::$_connections[$name]->length() > 0) {
while (static::$_connections[$name]->length() > 0) { if (static::$_connections[$name] instanceof Channel)
if (static::$_connections[$name] instanceof Channel) {
{ if (!Context::inCoroutine())
if (!Context::inCoroutine()) {
{ break;
break; }
} }
} $client = static::$_connections[$name]->pop();
$client = static::$_connections[$name]->pop(); if ($client instanceof StopHeartbeatCheck) {
if ($client instanceof StopHeartbeatCheck) { $client->stopHeartbeatCheck();
$client->stopHeartbeatCheck(); }
} }
} static::$_connections[$name] = null;
static::$_connections[$name] = null; unset(static::$_connections[$name]);
unset(static::$_connections[$name]); }
}
/**
/** * @return Channel[]
* @return Channel[] */
*/ protected function getChannels(): array
protected function getChannels(): array {
{ return static::$_connections;
return static::$_connections; }
}
}
}
+122 -126
View File
@@ -1,126 +1,122 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Pool; namespace Kiri\Pool;
use Closure; use Closure;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Context; use Kiri\Context;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri;
/** /**
* Class RedisClient * Class RedisClient
* @package Kiri\Kiri\Pool * @package Kiri\Pool
*/ */
class Redis extends Component class Redis extends Component
{ {
use Alias; use Alias;
/** /**
* @param mixed $config * @param mixed $config
* @param bool $isMaster * @param bool $isMaster
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function get(mixed $config, bool $isMaster = false): mixed public function get(mixed $config, bool $isMaster = false): mixed
{ {
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster); $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
if (Context::hasContext($coroutineName)) { if (Context::hasContext($coroutineName)) {
return Context::getContext($coroutineName); return Context::getContext($coroutineName);
} }
$pool = $config['pool'] ?? ['min' => 1, 'max' => 100]; $pool = $config['pool'] ?? ['min' => 1, 'max' => 100];
$clients = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $pool['min'] ?? 1); $clients = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $pool['min'] ?? 1);
return Context::setContext($coroutineName, $clients); return Context::setContext($coroutineName, $clients);
} }
/** /**
* @param string $name * @param string $name
* @param mixed $config * @param mixed $config
* @return Closure * @return Closure
*/ */
public function create(string $name, mixed $config): Closure public function create(string $name, mixed $config): Closure
{ {
return static function () use ($name, $config) { return static function () use ($name, $config) {
return Kiri::getDi()->create(\Kiri\Cache\Base\Redis::class, [ return Kiri::getDi()->create(\Kiri\Cache\Base\Redis::class, [$config]);
$config['host'], (int)$config['port'], $config['databases'] ?? 0, };
$config['auth'], $config['prefix'] ?? '', $config['timeout'] ?? 30, }
$config['read_timeout'] ?? 30
]);
}; /**
} * @param array $config
* @param bool $isMaster
* @throws ConfigException
/** * @throws Exception
* @param array $config */
* @param bool $isMaster public function release(array $config, bool $isMaster = false)
* @throws ConfigException {
* @throws Exception $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
*/ if (!Context::hasContext($coroutineName)) {
public function release(array $config, bool $isMaster = false) return;
{ }
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
if (!Context::hasContext($coroutineName)) { $this->getPool()->push($coroutineName, Context::getContext($coroutineName));
return; Context::remove($coroutineName);
} }
$this->getPool()->push($coroutineName, Context::getContext($coroutineName)); /**
Context::remove($coroutineName); * @param array $config
} * @param bool $isMaster
* @throws Exception
/** */
* @param array $config public function destroy(array $config, bool $isMaster = false)
* @param bool $isMaster {
* @throws Exception $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
*/ $this->getPool()->clean($coroutineName);
public function destroy(array $config, bool $isMaster = false) Context::remove($coroutineName);
{ }
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
$this->getPool()->clean($coroutineName);
Context::remove($coroutineName); /**
} * @param array $config
* @param bool $isMaster
* @throws Exception
/** */
* @param array $config public function connection_clear(array $config, bool $isMaster = false)
* @param bool $isMaster {
* @throws Exception $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
*/ $this->getPool()->clean($coroutineName);
public function connection_clear(array $config, bool $isMaster = false) }
{
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
$this->getPool()->clean($coroutineName); /**
} * @return Pool
* @throws Exception
*/
/** public function getPool(): Pool
* @return Pool {
* @throws Exception return Kiri::getDi()->get(Pool::class);
*/ }
public function getPool(): Pool
{
return Kiri::getDi()->get(Pool::class); /**
} * @param $name
* @param $isMaster
* @param $max
/** * @throws Exception
* @param $name */
* @param $isMaster public function initConnections($name, $isMaster, $max)
* @param $max {
* @throws Exception $this->getPool()->initConnections($name, $isMaster, $max);
*/ }
public function initConnections($name, $isMaster, $max)
{
$this->getPool()->initConnections($name, $isMaster, $max); }
}
}
+11 -11
View File
@@ -1,11 +1,11 @@
<?php <?php
namespace Kiri\Pool; namespace Kiri\Pool;
interface StopHeartbeatCheck interface StopHeartbeatCheck
{ {
public function stopHeartbeatCheck(); public function stopHeartbeatCheck();
} }
+27 -27
View File
@@ -1,27 +1,27 @@
<?php <?php
namespace Kiri; namespace Kiri;
class Proxy class Proxy
{ {
/** /**
* Proxy constructor. * Proxy constructor.
* @param IProxy $IProxy * @param IProxy $IProxy
*/ */
public function __construct(public IProxy $IProxy) public function __construct(public IProxy $IProxy)
{ {
} }
/** /**
* @return mixed * @return mixed
*/ */
public function execute(): mixed public function execute(): mixed
{ {
return $this->IProxy->execute(); return $this->IProxy->execute();
} }
} }
+101 -101
View File
@@ -1,101 +1,101 @@
<?php <?php
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\Input; use Kiri\Abstracts\Config;
use Symfony\Component\Console\Command\Command; use Kiri\Abstracts\Input;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Kiri;
/**
* Class Runtime /**
* @package Kiri * Class Runtime
*/ * @package Kiri
class Runtime extends Command */
{ class Runtime extends Command
{
public string $command = 'runtime:builder';
public string $command = 'runtime:builder';
public string $description = 'create app file cache';
public string $description = 'create app file cache';
const CACHE_NAME = '.runtime.cache';
const CONFIG_NAME = '.config.cache'; const CACHE_NAME = '.runtime.cache';
const CONFIG_NAME = '.config.cache';
protected function configure()
{ protected function configure()
$this->setName('runtime:builder'); {
} $this->setName('runtime:builder');
}
/**
* @param InputInterface $input /**
* @param OutputInterface $output * @param InputInterface $input
* @return int * @param OutputInterface $output
* @throws Exception * @return int
*/ * @throws Exception
public function execute(InputInterface $input, OutputInterface $output): int */
{ public function execute(InputInterface $input, OutputInterface $output): int
// TODO: Implement onHandler() method. {
$annotation = Kiri::app()->getAnnotation(); // TODO: Implement onHandler() method.
$annotation = Kiri::app()->getAnnotation();
$runtime = storage(static::CACHE_NAME);
$config = storage(static::CONFIG_NAME); $runtime = storage(static::CACHE_NAME);
$config = storage(static::CONFIG_NAME);
Kiri::writeFile($config, $this->configEach());
Kiri::writeFile($runtime, serialize($annotation->getLoader())); Kiri::writeFile($config, $this->configEach());
Kiri::writeFile($runtime, serialize($annotation->getLoader()));
return 1;
} return 1;
}
/**
* @return string /**
* @throws Exception * @return string
*/ * @throws Exception
public function configEach(): string */
{ public function configEach(): string
$array = []; {
$configs = Kiri::app()->getConfig(); $array = [];
foreach ($configs->getData() as $key => $datum) { foreach (Config::getData() as $key => $datum) {
if ($datum instanceof \Closure) { if ($datum instanceof \Closure) {
continue; continue;
} }
if (is_array($datum)) { if (is_array($datum)) {
$array[$key] = $this->arrayEach($datum); $array[$key] = $this->arrayEach($datum);
} else { } else {
$array[$key] = $datum; $array[$key] = $datum;
} }
} }
return serialize($array); return serialize($array);
} }
/** /**
* @param array $value * @param array $value
* @return array * @return array
*/ */
private function arrayEach(array $value): array private function arrayEach(array $value): array
{ {
$array = []; $array = [];
foreach ($value as $key => $item) { foreach ($value as $key => $item) {
if ($item instanceof \Closure) { if ($item instanceof \Closure) {
continue; continue;
} }
if (is_array($item)) { if (is_array($item)) {
$array[$key] = $this->arrayEach($item); $array[$key] = $this->arrayEach($item);
} else { } else {
$array[$key] = $item; $array[$key] = $item;
} }
} }
return $array; return $array;
} }
} }
+10 -10
View File
@@ -1,10 +1,10 @@
<?php <?php
namespace Kiri; namespace Kiri;
interface ToArray interface ToArray
{ {
public function toArray(); public function toArray();
} }
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace Kiri\Gateway;
class Collector
{
public function get()
{
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace Kiri\Gateway;
use Swoole\Http\Request;
use Swoole\Http\Response;
class GatewayServer
{
/**
* @param Request $request
* @param Response $response
*/
public function onRequest(Request $request, Response $response)
{
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace Kiri\Gateway;
class HashMap
{
const HTTP = 1;
const TCP = 2;
const UDP = 2;
public string $domain;
public string $path;
public string $scheme;
public string $method;
public string $proxy_host;
public string $proxy_port;
public int $type = self::HTTP;
}
+342 -343
View File
@@ -1,343 +1,342 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: 向林 * User: 向林
* Date: 2016/8/9 0009 * Date: 2016/8/9 0009
* Time: 17:43 * Time: 17:43
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Database\Connection; use Database\Connection;
use Database\Db; use Database\Db;
use Exception; use Exception;
use Kiri\Cache\Redis; use Kiri\Cache\Redis;
use Kiri\Kiri; use Kiri;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
/** /**
* Class gii * Class gii
* *
* @package Inter\utility * @package Inter\utility
*/ */
class Gii class Gii
{ {
private ?string $tableName = NULL; private ?string $tableName = NULL;
/** @var null|Connection */ /** @var null|Connection */
private ?Connection $db; private ?Connection $db;
private InputInterface $input; private InputInterface $input;
public string $modelPath = APP_PATH . 'app/Model/'; public string $modelPath = APP_PATH . 'app/Model/';
public string $modelNamespace = 'App\\Model\\'; public string $modelNamespace = 'App\\Model\\';
public string $controllerPath = APP_PATH . 'app/Http/Controller/'; public string $controllerPath = APP_PATH . 'app/Http/Controller/';
public string $controllerNamespace = 'App\\Controller\\'; public string $controllerNamespace = 'App\\Controller\\';
public static array $createSqls = []; public static array $createSqls = [];
public array $keyword = [ public array $keyword = [
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL' 'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL'
]; ];
/** /**
* @param Connection|null $db * @param Connection|null $db
* *
* @param InputInterface $input * @param InputInterface $input
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function run(?Connection $db, InputInterface $input): array public function run(?Connection $db, InputInterface $input): array
{ {
return $this->gen($input, $db); return $this->gen($input, $db);
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
* @param $db * @param $db
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function gen(InputInterface $input, $db): array public function gen(InputInterface $input, $db): array
{ {
$this->input = $input; $this->input = $input;
$this->db = $db; $this->db = $db;
$make = $this->input->getArgument('action'); $make = $this->input->getOption('make');
if (empty($make)) { if (empty($make)) {
throw new Exception('构建类型不能为空~'); throw new Exception('构建类型不能为空~');
} }
switch (strtolower($make)) { switch (strtolower($make)) {
case 'task': case 'task':
$task = new GiiTask(); $task = new GiiTask();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'middleware': case 'middleware':
$task = new GiiMiddleware(); $task = new GiiMiddleware();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'rpc-client': case 'rpc-client':
$task = new GiiRpcClient(); $task = new GiiRpcClient();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'rpc-service': case 'rpc-service':
$task = new GiiRpcService(); $task = new GiiRpcService();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'json-rpc': case 'json-rpc':
$task = new GiiJsonRpc(); $task = new GiiJsonRpc();
$task->setInput($this->input); $task->setInput($this->input);
return $task->create(); return $task->create();
default: default:
return $this->getModel($make, $input); return $this->getModel($make, $input);
} }
} }
/** /**
* @param $make * @param $make
* @param $input * @param $input
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
private function getModel($make, $input): array private function getModel($make, $input): array
{ {
return $this->makeByDatabases($make, $input); return $this->makeByDatabases($make, $input);
} }
/** /**
* @param $make * @param $make
* @param InputInterface $input * @param InputInterface $input
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
private function makeByDatabases($make, InputInterface $input): array private function makeByDatabases($make, InputInterface $input): array
{ {
$redis = Kiri::getDi()->get(Redis::class); if ($input->hasOption('name')) {
if ($input->hasArgument('name')) { $this->tableName = $input->getOption('name');
$this->tableName = $input->getArgument('name'); }
$redis->del('column:' . $this->tableName); return match ($make) {
} 'controller' => $this->getTable(1, 0),
return match ($make) { 'model' => $this->getTable(0, 1),
'controller' => $this->getTable(1, 0), default => [],
'model' => $this->getTable(0, 1), };
default => [], }
};
}
/**
* @param $controller
/** * @param $model
* @param $controller * @return array
* @param $model *
* @return array * @throws Exception
* */
* @throws Exception private function getTable($controller, $model): array
*/ {
private function getTable($controller, $model): array $tables = $this->getFields($this->getTables());
{ if (empty($tables)) {
$tables = $this->getFields($this->getTables()); return [];
if (empty($tables)) { }
return [];
} $fileList = [];
foreach ($tables as $key => $val) {
$fileList = []; $data = $this->createModelFile($key, $val);
foreach ($tables as $key => $val) { if ($controller == 1) {
$data = $this->createModelFile($key, $val); $fileList[] = $this->generateController($data);
if ($controller == 1) { }
$fileList[] = $this->generateController($data); if ($model == 1) {
} $fileList[] = $this->generateModel($data);
if ($model == 1) { }
$fileList[] = $this->generateModel($data); }
} return $fileList;
} }
return $fileList;
} /**
* @param array $data
/** * @return string
* @param array $data * @throws Exception
* @return string */
* @throws Exception private function generateModel(array $data): string
*/ {
private function generateModel(array $data): string $controller = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']);
{ $controller->setConnection($this->db);
$controller = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']); $controller->setModelPath($this->modelPath);
$controller->setConnection($this->db); $controller->setModelNamespace($this->modelNamespace);
$controller->setModelPath($this->modelPath); $controller->setInput($this->input);
$controller->setModelNamespace($this->modelNamespace); // $controller->setModule($this->input->getArgument('module'));
$controller->setInput($this->input); $controller->setControllerPath($this->controllerPath);
// $controller->setModule($this->input->getArgument('module')); $controller->setControllerNamespace($this->controllerNamespace);
$controller->setControllerPath($this->controllerPath); return $controller->generate();
$controller->setControllerNamespace($this->controllerNamespace); }
return $controller->generate();
} /**
* @param array $data
/** * @return string
* @param array $data * @throws Exception
* @return string */
* @throws Exception private function generateController(array $data): string
*/ {
private function generateController(array $data): string $controller = new GiiController($data['classFileName'], $data['fields']);
{ $controller->setConnection($this->db);
$controller = new GiiController($data['classFileName'], $data['fields']); $controller->setModelPath($this->modelPath);
$controller->setConnection($this->db); $controller->setInput($this->input);
$controller->setModelPath($this->modelPath); $controller->setModelNamespace($this->modelNamespace);
$controller->setInput($this->input); $controller->setControllerPath($this->controllerPath);
$controller->setModelNamespace($this->modelNamespace); $controller->setModule($this->input->getArgument('module'));
$controller->setControllerPath($this->controllerPath); $controller->setControllerNamespace($this->controllerNamespace);
$controller->setModule($this->input->getArgument('module')); return $controller->generate();
$controller->setControllerNamespace($this->controllerNamespace); }
return $controller->generate();
} /**
* @return array|string|null
/** * @throws Exception
* @return array|string|null */
* @throws Exception private function getTables(): array|string|null
*/ {
private function getTables(): array|string|null if (empty($this->tableName)) {
{ return $this->showAll();
if (empty($this->tableName)) { }
return $this->showAll(); $res = $this->tableName;
} if (is_string($res)) {
$res = $this->tableName; $res = explode(',', $this->tableName);
if (is_string($res)) { }
$res = explode(',', $this->tableName); if (empty($res)) {
} return [];
if (empty($res)) { }
return []; return $res;
} }
return $res;
} /**
* @return array
/** * @throws Exception
* @return array */
* @throws Exception private function showAll(): array
*/ {
private function showAll(): array $res = [];
{ $_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db);
$res = []; if (empty($_tables)) {
$_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db); return $res;
if (empty($_tables)) { }
return $res; foreach ($_tables as $key => $val) {
} $res[] = array_shift($val);
foreach ($_tables as $key => $val) { }
$res[] = array_shift($val); return $res;
} }
return $res;
} /**
* @param $table
/** * @return bool|int|null
* @param $table * @throws Exception
* @return bool|int|null */
* @throws Exception private function getIndex($table): bool|int|null
*/ {
private function getIndex($table): bool|int|null $data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db);
{
$data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db); return empty($data) ? NULL : $data[0];
}
return empty($data) ? NULL : $data[0];
} /**
* @param $tables
/** *
* @param $tables * @return array
* * @throws
* @return array */
* @throws private function getFields($tables): array
*/ {
private function getFields($tables): array $res = [];
{ if (!is_array($tables)) {
$res = []; $tables = [$tables];
if (!is_array($tables)) { }
$tables = [$tables]; foreach ($tables as $key => $val) {
} if (empty($val)) continue;
foreach ($tables as $key => $val) { $_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db);
if (empty($val)) continue; if (empty($_tmp)) {
$_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db); continue;
if (empty($_tmp)) { }
continue; $res[$val] = $_tmp;
} }
$res[$val] = $_tmp; return $res;
} }
return $res;
} /**
* @param $tableName
/** * @param $tables
* @param $tableName *
* @param $tables * @return array
* * @throws Exception
* @return array */
* @throws Exception public function createModelFile($tableName, $tables): array
*/ {
public function createModelFile($tableName, $tables): array $res = $visible = $fields = $keys = [];
{ foreach ($tables as $_key => $_val) {
$res = $visible = $fields = $keys = []; $keys = $tableName;
foreach ($tables as $_key => $_val) { if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') {
$keys = $tableName; $keys = $tableName;
if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') { }
$keys = $tableName; if (!isset($keys) && !($index = $this->getIndex($tableName))) {
} $keys = $index['Column_name'];
if (!isset($keys) && !($index = $this->getIndex($tableName))) { }
$keys = $index['Column_name']; if (in_array(strtoupper($_val['Field']), $this->keyword)) {
} throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"');
if (in_array(strtoupper($_val['Field']), $this->keyword)) { }
throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"'); array_push($visible, $this->createVisible($_val['Field']));
} array_push($fields, $_val);
array_push($visible, $this->createVisible($_val['Field'])); $res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
array_push($fields, $_val); }
$res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
} $classFileName = $this->getClassName($tableName);
$classFileName = $this->getClassName($tableName); return [
'classFileName' => $classFileName,
return [ 'tableName' => $keys,
'classFileName' => $classFileName, 'visible' => $visible,
'tableName' => $keys, 'fields' => $fields,
'visible' => $visible, 'res' => $res,
'fields' => $fields, ];
'res' => $res, }
];
} /**
* @param $field
/** * @return string
* @param $field * 创建变量注释
* @return string */
* 创建变量注释 private function createVisible($field): string
*/ {
private function createVisible($field): string return '
{ * @property $' . $field;
return ' }
* @property $' . $field;
} /**
* @param $field
/** * @param $comment
* @param $field * @return string
* @param $comment * 暂时不知道干嘛用的
* @return string */
* 暂时不知道干嘛用的 private function createSetFunc($field, $comment): string
*/ {
private function createSetFunc($field, $comment): string return '
{ ' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
return ' }
' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
} /**
* @param $tableName
/** * @return string
* @param $tableName * 构建类名称
* @return string */
* 构建类名称 private function getClassName($tableName): string
*/ {
private function getClassName($tableName): string $res = [];
{ $tableName = str_replace($this->db->tablePrefix,'', $tableName);
$res = []; foreach (explode('_', $tableName) as $n => $val) {
foreach (explode('_', $tableName) as $n => $val) { $res[] = ucfirst($val);
$res[] = ucfirst($val); }
} return implode('', $res);
return implode('', $res); }
}
}
}
+411 -411
View File
@@ -1,411 +1,411 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Database\Connection; use Database\Connection;
use Exception; use Exception;
use Kiri\Core\Json; use Kiri\Core\Json;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
/** /**
* Class GiiBase * Class GiiBase
* @package Gii * @package Gii
*/ */
abstract class GiiBase abstract class GiiBase
{ {
public array $fileList = []; public array $fileList = [];
protected InputInterface $input; protected InputInterface $input;
public string $modelPath = APP_PATH . 'app/Model/'; public string $modelPath = APP_PATH . 'app/Model/';
public string $modelNamespace = 'App\Model\\'; public string $modelNamespace = 'App\Model\\';
public string $controllerPath = APP_PATH . 'app/Http/Controller/'; public string $controllerPath = APP_PATH . 'app/Http/Controller/';
public string $controllerNamespace = 'App\\Controller\\'; public string $controllerNamespace = 'App\\Controller\\';
public ?string $module = null; public ?string $module = null;
public array $rules = []; public array $rules = [];
public array $type = [ public array $type = [
'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'], 'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'],
'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'], 'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'],
'date' => ['date'], 'date' => ['date'],
'time' => ['time'], 'time' => ['time'],
'year' => ['year'], 'year' => ['year'],
'datetime' => ['datetime'], 'datetime' => ['datetime'],
'timestamp' => ['timestamp'], 'timestamp' => ['timestamp'],
'float' => ['float', 'double', 'decimal',], 'float' => ['float', 'double', 'decimal',],
]; ];
public ?string $tableName = NULL; public ?string $tableName = NULL;
public ?Connection $db = null; public ?Connection $db = null;
/** /**
* @param string $modelPath * @param string $modelPath
*/ */
public function setModelPath(string $modelPath): void public function setModelPath(string $modelPath): void
{ {
$this->modelPath = $modelPath; $this->modelPath = $modelPath;
} }
/** /**
* @param string $modelNamespace * @param string $modelNamespace
*/ */
public function setModelNamespace(string $modelNamespace): void public function setModelNamespace(string $modelNamespace): void
{ {
$this->modelNamespace = $modelNamespace; $this->modelNamespace = $modelNamespace;
} }
/** /**
* @param string $controllerPath * @param string $controllerPath
*/ */
public function setControllerPath(string $controllerPath): void public function setControllerPath(string $controllerPath): void
{ {
$this->controllerPath = $controllerPath; $this->controllerPath = $controllerPath;
} }
/** /**
* @param $module * @param $module
*/ */
public function setModule($module) public function setModule($module)
{ {
$this->module = $module; $this->module = $module;
} }
/** /**
* @param string $controllerNamespace * @param string $controllerNamespace
*/ */
public function setControllerNamespace(string $controllerNamespace): void public function setControllerNamespace(string $controllerNamespace): void
{ {
$this->controllerNamespace = $controllerNamespace; $this->controllerNamespace = $controllerNamespace;
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
*/ */
public function setInput(InputInterface $input) public function setInput(InputInterface $input)
{ {
$this->input = $input; $this->input = $input;
} }
/** /**
* @param ReflectionClass $object * @param ReflectionClass $object
* @param $className * @param $className
* *
* @return string * @return string
*/ */
public function getUseContent(ReflectionClass $object, $className): string public function getUseContent(ReflectionClass $object, $className): string
{ {
if (empty($object)) { if (empty($object)) {
return ''; return '';
} }
$file = $this->getFilePath($className); $file = $this->getFilePath($className);
if (!file_exists($file)) { if (!file_exists($file)) {
return ''; return '';
} }
$content = file_get_contents($file); $content = file_get_contents($file);
$explode = explode(PHP_EOL, $content); $explode = explode(PHP_EOL, $content);
$exists = array_slice($explode, 0, $object->getStartLine()); $exists = array_slice($explode, 0, $object->getStartLine());
$_tmp = []; $_tmp = [];
foreach ($exists as $key => $val) { foreach ($exists as $key => $val) {
if (trim($val) == '/**') { if (trim($val) == '/**') {
break; break;
} }
$_tmp[] = $val; $_tmp[] = $val;
} }
return trim(implode(PHP_EOL, $_tmp)); return trim(implode(PHP_EOL, $_tmp));
} }
/** /**
* @param string $fileName * @param string $fileName
* @param ReflectionClass $class * @param ReflectionClass $class
* @return string * @return string
*/ */
protected function getImports(string $fileName, ReflectionClass $class): string protected function getImports(string $fileName, ReflectionClass $class): string
{ {
$startLine = 1; $startLine = 1;
$array = []; $array = [];
$fileOpen = fopen($fileName, 'r'); $fileOpen = fopen($fileName, 'r');
while (($content = fgets($fileOpen)) !== false) { while (($content = fgets($fileOpen)) !== false) {
if (str_starts_with($content, 'use ')) { if (str_starts_with($content, 'use ')) {
$array[] = $content; $array[] = $content;
} }
if ($startLine == $class->getStartLine()) { if ($startLine == $class->getStartLine()) {
break; break;
} }
++$startLine; ++$startLine;
} }
return implode($array); return implode($array);
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @return string * @return string
* @throws ReflectionException * @throws ReflectionException
*/ */
protected function getClassProperty(ReflectionClass $class): string protected function getClassProperty(ReflectionClass $class): string
{ {
$html = ''; $html = '';
$rc = $class->getParentClass()->getConstants(); $rc = $class->getParentClass()->getConstants();
foreach ($class->getConstants() as $key => $val) { foreach ($class->getConstants() as $key => $val) {
if (isset($rc[$key])) { if (isset($rc[$key])) {
continue; continue;
} }
if (is_numeric($val)) { if (is_numeric($val)) {
$html .= ' $html .= '
const ' . $key . ' = ' . $val . ';' . "\n"; const ' . $key . ' = ' . $val . ';' . "\n";
} else { } else {
$html .= ' $html .= '
const ' . $key . ' = \'' . $val . '\';' . "\n"; const ' . $key . ' = \'' . $val . '\';' . "\n";
} }
} }
foreach ($class->getDefaultProperties() as $key => $val) { foreach ($class->getDefaultProperties() as $key => $val) {
$property = $class->getProperty($key); $property = $class->getProperty($key);
if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') { if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') {
continue; continue;
} }
if ($property->class != $class->getName()) continue; if ($property->class != $class->getName()) continue;
if (is_array($val)) { if (is_array($val)) {
$val = '[\'' . implode('\', \'', $val) . '\']'; $val = '[\'' . implode('\', \'', $val) . '\']';
} else if (!is_numeric($val)) { } else if (!is_numeric($val)) {
$val = '\'' . $val . '\''; $val = '\'' . $val . '\'';
} }
if ($property->isProtected()) { if ($property->isProtected()) {
$debug = 'protected'; $debug = 'protected';
} else if ($property->isPrivate()) { } else if ($property->isPrivate()) {
$debug = 'private'; $debug = 'private';
} else { } else {
$debug = 'public'; $debug = 'public';
} }
if ($property->hasType()) { if ($property->hasType()) {
$type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n"; $type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n";
} else { } else {
$type = ' $' . $key . ' = ' . $val . ';' . "\n"; $type = ' $' . $key . ' = ' . $val . ';' . "\n";
} }
if ($property->isStatic()) { if ($property->isStatic()) {
$html .= ' $html .= '
' . $debug . ' static' . $type; ' . $debug . ' static' . $type;
} else { } else {
$html .= ' $html .= '
' . $debug . $type; ' . $debug . $type;
} }
} }
return $html; return $html;
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @param array $filters * @param array $filters
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
protected function getClassMethods(ReflectionClass $class, array $filters = []): string protected function getClassMethods(ReflectionClass $class, array $filters = []): string
{ {
$methods = $class->getMethods(); $methods = $class->getMethods();
$classFileName = str_replace(APP_PATH, '', $class->getFileName()); $classFileName = str_replace(APP_PATH, '', $class->getFileName());
$content = []; $content = [];
if (!empty($methods)) foreach ($methods as $key => $val) { if (!empty($methods)) foreach ($methods as $key => $val) {
if ($val->class != $class->getName()) continue; if ($val->class != $class->getName()) continue;
if (in_array($val->name, $filters)) continue; if (in_array($val->name, $filters)) continue;
$over = " $over = "
" . $val->getDocComment() . "\n"; " . $val->getDocComment() . "\n";
$attributes = $val->getAttributes(); $attributes = $val->getAttributes();
if (!empty($attributes)) { if (!empty($attributes)) {
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$explode = explode('\\', $attribute->getName()); $explode = explode('\\', $attribute->getName());
$_array = []; $_array = [];
foreach ($attribute->getArguments() as $_key => $argument) { foreach ($attribute->getArguments() as $_key => $argument) {
$argument = $this->resolveArray($argument); $argument = $this->resolveArray($argument);
if (is_numeric($_key)) { if (is_numeric($_key)) {
$_array[] = $argument; $_array[] = $argument;
} else { } else {
$_array[] = $_key . ': ' . $argument . ''; $_array[] = $_key . ': ' . $argument . '';
} }
} }
if (empty($_array)) { if (empty($_array)) {
$end = " #[" . end($explode) . "] $end = " #[" . end($explode) . "]
"; ";
} else { } else {
$end = " #[" . end($explode) . "(" . implode(',', $_array) . ")] $end = " #[" . end($explode) . "(" . implode(',', $_array) . ")]
"; ";
} }
if (str_contains($over, $end)) { if (str_contains($over, $end)) {
$over = str_replace($end, '', $over); $over = str_replace($end, '', $over);
} }
$over .= $end; $over .= $end;
} }
} }
$func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n"; $func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
$content[] = $over . $func; $content[] = $over . $func;
} }
return implode(PHP_EOL, $content); return implode(PHP_EOL, $content);
} }
/** /**
* @param $argument * @param $argument
* @return string * @return string
*/ */
private function resolveArray($argument): string private function resolveArray($argument): string
{ {
if (is_array($argument)) { if (is_array($argument)) {
$__array = []; $__array = [];
foreach ($argument as $key => $value) { foreach ($argument as $key => $value) {
if (is_string($value)) { if (is_string($value)) {
if (str_contains($value, '\\') && class_exists($value)) { if (str_contains($value, '\\') && class_exists($value)) {
$explode_class = explode('\\', $value); $explode_class = explode('\\', $value);
$__array[] = end($explode_class) . '::class'; $__array[] = end($explode_class) . '::class';
} else { } else {
$__array[] = '\'' . $value . '\''; $__array[] = '\'' . $value . '\'';
} }
} else { } else {
$value = str_replace('{', '[', Json::encode($value)); $value = str_replace('{', '[', Json::encode($value));
$value = str_replace('}', ']', Json::encode($value)); $value = str_replace('}', ']', Json::encode($value));
$value = str_replace(':', '=>', Json::encode($value)); $value = str_replace(':', '=>', Json::encode($value));
$value = preg_replace('/"\d+"\=\>/', '', $value); $value = preg_replace('/"\d+"\=\>/', '', $value);
$__array[] = $value; $__array[] = $value;
} }
} }
$argument = '[' . implode(', ', $__array) . ']'; $argument = '[' . implode(', ', $__array) . ']';
} else { } else {
$argument = '\'' . $argument . '\''; $argument = '\'' . $argument . '\'';
} }
return $argument; return $argument;
} }
/** /**
* @param $fields * @param $fields
* @return mixed 返回表主键 * @return mixed 返回表主键
* 返回表主键 * 返回表主键
*/ */
public function getPrimaryKey($fields): mixed public function getPrimaryKey($fields): mixed
{ {
$condition = ['PRI', 'UNI']; $condition = ['PRI', 'UNI'];
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field['Extra'] == 'auto_increment') { if ($field['Extra'] == 'auto_increment') {
return $field['Field']; return $field['Field'];
} }
if (in_array($field['Key'], $condition)) { if (in_array($field['Key'], $condition)) {
return $field['Field']; return $field['Field'];
} }
} }
return null; return null;
} }
/** /**
* @param $className * @param $className
* @return string * @return string
*/ */
private function getFilePath($className): string private function getFilePath($className): string
{ {
if (strpos($className, '\\')) { if (strpos($className, '\\')) {
$className = str_replace('\\', '/', $className); $className = str_replace('\\', '/', $className);
} }
if (strpos($className, '\\')) { if (strpos($className, '\\')) {
$className = str_replace('\\', '/', $className); $className = str_replace('\\', '/', $className);
} }
return APP_PATH . $className; return APP_PATH . $className;
} }
/** /**
* @param ReflectionClass $object * @param ReflectionClass $object
* @param $className * @param $className
* @param $method * @param $method
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function getFuncLineContent(ReflectionClass $object, $className, $method): string public function getFuncLineContent(ReflectionClass $object, $className, $method): string
{ {
$fun = $object->getMethod($method); $fun = $object->getMethod($method);
$content = file_get_contents($this->getFilePath($className)); $content = file_get_contents($this->getFilePath($className));
$explode = explode(PHP_EOL, $content); $explode = explode(PHP_EOL, $content);
$exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1); $exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1);
return implode(PHP_EOL, $exists); return implode(PHP_EOL, $exists);
} }
/** /**
* @return array * @return array
*/ */
protected function getModelPath(): array protected function getModelPath(): array
{ {
$dbName = $this->db->id; $dbName = $this->db->id;
if (empty($dbName) || $dbName == 'db') { if (empty($dbName) || $dbName == 'db') {
$dbName = ''; $dbName = '';
} }
$modelPath = [ $modelPath = [
'namespace' => $this->modelNamespace, 'namespace' => $this->modelNamespace,
'path' => $this->modelPath, 'path' => $this->modelPath,
]; ];
if (!is_dir($modelPath['path'])) { if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']); mkdir($modelPath['path']);
} }
if (!empty($dbName)) { if (!empty($dbName)) {
$modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName); $modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName);
$modelPath['path'] = $this->modelPath . ucfirst($dbName); $modelPath['path'] = $this->modelPath . ucfirst($dbName);
} }
if (!is_dir($modelPath['path'])) { if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']); mkdir($modelPath['path']);
} }
return $modelPath; return $modelPath;
} }
/** /**
* @param $db * @param $db
*/ */
public function setConnection($db) public function setConnection($db)
{ {
$this->db = $db; $this->db = $db;
} }
/** /**
* @param $val * @param $val
* @return string * @return string
*/ */
protected function checkIsRequired($val): string protected function checkIsRequired($val): string
{ {
return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false'; return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false';
} }
/** /**
* @return array * @return array
*/ */
public function getFileLists(): array public function getFileLists(): array
{ {
return $this->fileList; return $this->fileList;
} }
} }
+76 -76
View File
@@ -1,76 +1,76 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Exception; use Exception;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
/** /**
* Class Command * Class Command
* @package Http * @package Http
*/ */
class GiiCommand extends Command class GiiCommand extends Command
{ {
public string $command = 'sw:gii'; public string $command = 'sw:gii';
public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx'; public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx';
/** /**
* *
*/ */
protected function configure() protected function configure()
{ {
$this->setName('sw:gii') $this->setName('sw:gii')
->addArgument('action', InputArgument::REQUIRED) ->addOption('make','m', InputArgument::OPTIONAL)
->addArgument('name', InputArgument::OPTIONAL) ->addOption('name','t', InputArgument::OPTIONAL)
->addArgument('databases', InputArgument::OPTIONAL) ->addOption('databases','d', InputArgument::OPTIONAL)
->setDescription('./snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx'); ->setDescription('./snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx');
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
* @param OutputInterface $output * @param OutputInterface $output
* @return int * @return int
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {
/** @var Gii $gii */ /** @var Gii $gii */
$gii = Kiri::app()->get('gii'); $gii = Kiri::app()->get('gii');
$connections = Kiri::app()->get('db'); $connections = Kiri::app()->get('db');
if (($db = $input->getArgument('databases')) != null) { if (($db = $input->getOption('databases')) != null) {
$gii->run($connections->get($db), $input); $gii->run($connections->get($db), $input);
return 1; return 1;
} }
$action = $input->getArgument('action'); $action = $input->getOption('make');
if (!in_array($action, ['model', 'controller'])) { if (!in_array($action, ['model', 'controller'])) {
$gii->run(null, $input); $gii->run(null, $input);
return 1; return 1;
} }
$array = []; $array = [];
foreach (Config::get('databases.connections') as $key => $connection) { foreach (Config::get('databases.connections') as $key => $connection) {
$array[$key] = $gii->run($connections->get($key), $input); $array[$key] = $gii->run($connections->get($key), $input);
} }
$output->writeln(json_encode($array, JSON_UNESCAPED_UNICODE)); $output->writeln(json_encode($array, JSON_UNESCAPED_UNICODE));
return 1; return 1;
} }
} }
+536 -539
View File
File diff suppressed because it is too large Load Diff
+113 -113
View File
@@ -1,113 +1,113 @@
<?php <?php
namespace Gii; namespace Gii;
class GiiJsonRpc extends GiiBase class GiiJsonRpc extends GiiBase
{ {
/** /**
* @return array * @return array
*/ */
public function create(): array public function create(): array
{ {
return [ return [
$this->createInterface($this->input->getArgument('name')), $this->createInterface($this->input->getArgument('name')),
$this->createProducers($this->input->getArgument('name')), $this->createProducers($this->input->getArgument('name')),
$this->createConsumer($this->input->getArgument('name')), $this->createConsumer($this->input->getArgument('name')),
]; ];
} }
private function createInterface($name): string private function createInterface($name): string
{ {
$html = '<?php $html = '<?php
namespace Rpc; namespace Rpc;
interface ' . ucfirst($name) . 'RpcInterface interface ' . ucfirst($name) . 'RpcInterface
{ {
}'; }';
$name = ucfirst($name) . 'RpcInterface.php'; $name = ucfirst($name) . 'RpcInterface.php';
if (!is_dir(APP_PATH . '/rpc/')) { if (!is_dir(APP_PATH . '/rpc/')) {
mkdir(APP_PATH . '/rpc/'); mkdir(APP_PATH . '/rpc/');
} }
file_put_contents(APP_PATH . '/rpc/' . $name, $html); file_put_contents(APP_PATH . '/rpc/' . $name, $html);
return $name; return $name;
} }
private function createProducers($name): string private function createProducers($name): string
{ {
$html = '<?php $html = '<?php
namespace Rpc\Producers; namespace Rpc\Producers;
use Annotation\Target; use Kiri\Annotation\Target;
use Annotation\Mapping; use Kiri\Annotation\Mapping;
use Rpc\\' . ucfirst($name) . 'RpcInterface; use Rpc\\' . ucfirst($name) . 'RpcInterface;
use Exception; use Exception;
use Kiri\Rpc\JsonRpcConsumers; use Kiri\Rpc\JsonRpcConsumers;
#[Target] #[Target]
#[Mapping(' . ucfirst($name) . 'RpcInterface::class)] #[Mapping(' . ucfirst($name) . 'RpcInterface::class)]
class ' . ucfirst($name) . 'RpcService extends JsonRpcConsumers implements ' . ucfirst($name) . 'RpcInterface class ' . ucfirst($name) . 'RpcService extends JsonRpcConsumers implements ' . ucfirst($name) . 'RpcInterface
{ {
protected string $name = \'' . $name . '\'; protected string $name = \'' . $name . '\';
}'; }';
$name = ucfirst($name) . 'RpcService.php'; $name = ucfirst($name) . 'RpcService.php';
if (!is_dir(APP_PATH . '/rpc/Producers/')) { if (!is_dir(APP_PATH . '/rpc/Producers/')) {
mkdir(APP_PATH . '/rpc/Producers/'); mkdir(APP_PATH . '/rpc/Producers/');
} }
file_put_contents(APP_PATH . '/rpc/Producers/' . $name, $html); file_put_contents(APP_PATH . '/rpc/Producers/' . $name, $html);
return $name; return $name;
} }
private function createConsumer($name): string private function createConsumer($name): string
{ {
$html = '<?php $html = '<?php
namespace Rpc\Consumers; namespace Rpc\Consumers;
use Annotation\Target; use Kiri\Annotation\Target;
use Kiri\Rpc\Annotation\JsonRpc; use Kiri\Rpc\Annotation\JsonRpc;
use Http\Handler\Controller; use Kiri\Message\Handler\Controller;
use Rpc\\' . ucfirst($name) . 'RpcInterface; use Rpc\\' . ucfirst($name) . 'RpcInterface;
#[Target] #[Target]
#[JsonRpc(service: \'' . $name . '\', version: \'2.0\')] #[JsonRpc(service: \'' . $name . '\', version: \'2.0\')]
class ' . ucfirst($name) . 'RpcConsumer extends Controller implements ' . ucfirst($name) . 'RpcInterface class ' . ucfirst($name) . 'RpcConsumer extends Controller implements ' . ucfirst($name) . 'RpcInterface
{ {
}'; }';
$name = ucfirst($name) . 'RpcConsumer.php'; $name = ucfirst($name) . 'RpcConsumer.php';
if (!is_dir(APP_PATH . '/rpc/Consumers/')) { if (!is_dir(APP_PATH . '/rpc/Consumers/')) {
mkdir(APP_PATH . '/rpc/Consumers/'); mkdir(APP_PATH . '/rpc/Consumers/');
} }
file_put_contents(APP_PATH . '/rpc/Consumers/' . $name, $html); file_put_contents(APP_PATH . '/rpc/Consumers/' . $name, $html);
return $name; return $name;
} }
} }

Some files were not shown because too many files have changed in this diff Show More