update to build 417

This commit is contained in:
2021-09-01 14:14:00 +08:00
parent a13c4628f5
commit 229778ebf9
50 changed files with 1376 additions and 207 deletions

View File

@@ -24,7 +24,7 @@ trait CQAPI
return $this->processHttpAPI($connection, $reply, $function);
}
public function processWebsocketAPI($connection, $reply, $function = false) {
private function processWebsocketAPI($connection, $reply, $function = false) {
$api_id = ZMAtomic::get("wait_msg_id")->add(1);
$reply["echo"] = $api_id;
if (server()->push($connection->getFd(), json_encode($reply))) {
@@ -35,7 +35,7 @@ trait CQAPI
"self_id" => $connection->getOption("connect_id"),
"echo" => $api_id
];
return CoMessage::yieldByWS($obj, ["echo"], 60);
return CoMessage::yieldByWS($obj, ["echo"], 30);
}
return true;
} else {
@@ -63,7 +63,7 @@ trait CQAPI
* @return bool
* @noinspection PhpUnusedParameterInspection
*/
public function processHttpAPI($connection, $reply, $function = null): bool {
private function processHttpAPI($connection, $reply, $function = null): bool {
return false;
}

View File

@@ -5,6 +5,7 @@ namespace ZM\Annotation;
use Doctrine\Common\Annotations\AnnotationReader;
use ZM\Annotation\Interfaces\ErgodicAnnotation;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ReflectionClass;
use ReflectionException;
@@ -17,6 +18,7 @@ use ZM\Annotation\Http\MiddlewareClass;
use ZM\Annotation\Http\RequestMapping;
use ZM\Annotation\Interfaces\Level;
use ZM\Annotation\Module\Closed;
use ZM\Exception\AnnotationException;
use ZM\Utils\Manager\RouteManager;
use ZM\Utils\ZMUtil;
@@ -53,7 +55,7 @@ class AnnotationParser
*/
public function registerMods() {
foreach ($this->path_list as $path) {
Console::debug("parsing annotation in " . $path[0]);
Console::debug("parsing annotation in " . $path[0].":".$path[1]);
$all_class = ZMUtil::getClassesPsr4($path[0], $path[1]);
$this->reader = new AnnotationReader();
foreach ($all_class as $v) {
@@ -107,6 +109,7 @@ class AnnotationParser
unset($this->annotation_map[$v]);
continue 2;
} elseif ($vs instanceof MiddlewareClass) {
//注册中间件本身的类,标记到 middlewares 属性中
Console::debug("正在注册中间件 " . $reflection_class->getName());
$rs = $this->registerMiddleware($vs, $reflection_class);
$this->middlewares[$rs["name"]] = $rs;
@@ -193,6 +196,12 @@ class AnnotationParser
return $result;
}
/**
* @internal 用于 level 排序
* @param $events
* @param string $class_name
* @param string $prefix
*/
public function sortByLevel(&$events, string $class_name, $prefix = "") {
if (is_a($class_name, Level::class, true)) {
$class_name .= $prefix;
@@ -203,4 +212,22 @@ class AnnotationParser
});
}
}
/**
* @throws AnnotationException
*/
public function verifyMiddlewares() {
if ((ZMConfig::get("global", "runtime")["middleware_error_policy"] ?? 1) === 2) {
//我承认套三层foreach很不优雅但是这个会很快的。
foreach($this->middleware_map as $class => $v) {
foreach ($v as $method => $vs) {
foreach($vs as $mid) {
if (!isset($this->middlewares[$mid->middleware])) {
throw new AnnotationException("Annotation parse error: Unknown MiddlewareClass named \"{$mid->middleware}\"!");
}
}
}
}
}
}
}

View File

@@ -18,8 +18,8 @@ class ModuleListCommand extends Command
protected static $defaultName = 'module:list';
protected function configure() {
$this->setDescription("Build an \".phar\" file | 将项目构建一个phar包");
$this->setHelp("此功能将会把炸毛框架的模块打包为\".phar\",供发布和执行");
$this->setDescription("查看所有模块信息");
$this->setHelp("此功能将会把炸毛框架的模块列举出来");
// ...
}
@@ -31,6 +31,7 @@ class ModuleListCommand extends Command
}
//定义常量
/** @noinspection PhpIncludeInspection */
include_once DataProvider::getFrameworkRootDir() . "/src/ZM/global_defines.php";
Console::init(
@@ -47,7 +48,7 @@ class ModuleListCommand extends Command
foreach ($list as $v) {
echo "[" . Console::setColor($v["name"], "green") . "]" . PHP_EOL;
$out_list = ["类型" => "source"];
$out_list = ["类型" => "源码(source)"];
if (isset($v["version"])) $out_list["版本"] = $v["version"];
if (isset($v["description"])) $out_list["描述"] = $v["description"];
$out_list["目录"] = str_replace(DataProvider::getSourceRootDir() . "/", "", $v["module-path"]);
@@ -59,7 +60,7 @@ class ModuleListCommand extends Command
$list = ModuleManager::getPackedModules();
foreach ($list as $v) {
echo "[" . Console::setColor($v["name"], "gold") . "]" . PHP_EOL;
$out_list = ["类型" => "archive(phar)"];
$out_list = ["类型" => "模块包(phar)"];
if (isset($v["module-config"]["version"])) $out_list["版本"] = $v["module-config"]["version"];
if (isset($v["module-config"]["description"])) $out_list["描述"] = $v["module-config"]["description"];
$out_list["位置"] = str_replace(DataProvider::getSourceRootDir() . "/", "", $v["phar-path"]);

View File

@@ -21,7 +21,7 @@ class ModulePackCommand extends Command
protected function configure() {
$this->addArgument("module-name", InputArgument::REQUIRED);
$this->setDescription("Build an \".phar\" file | 将项目构建一个phar包");
$this->setDescription("将配置好的模块构建一个phar包");
$this->setHelp("此功能将会把炸毛框架的模块打包为\".phar\",供发布和执行。");
$this->addOption("target", "D", InputOption::VALUE_REQUIRED, "Output Directory | 指定输出目录");
// ...

View File

@@ -22,11 +22,12 @@ class ModuleUnpackCommand extends Command
protected function configure() {
$this->setDefinition([
new InputArgument("module-name", InputArgument::REQUIRED),
new InputOption("override-light-cache", null, null, "覆盖现有的LightCache项目"),
new InputOption("override-zm-data", null, null, "覆盖现有的zm_data文件"),
new InputOption("override-source", null, null, "覆盖现有的源码文件")
new InputOption("overwrite-light-cache", null, null, "覆盖现有的LightCache项目"),
new InputOption("overwrite-zm-data", null, null, "覆盖现有的zm_data文件"),
new InputOption("overwrite-source", null, null, "覆盖现有的源码文件"),
new InputOption("ignore-depends", null, null, "解包时忽略检查依赖")
]);
$this->setDescription("Unpack a phar module into src directory");
$this->setDescription("解包一个phar模块到src目录");
$this->setHelp("此功能将phar格式的模块包解包到src目录下。");
// ...
}
@@ -39,6 +40,7 @@ class ModuleUnpackCommand extends Command
}
//定义常量
/** @noinspection PhpIncludeInspection */
include_once DataProvider::getFrameworkRootDir()."/src/ZM/global_defines.php";
Console::init(

View File

@@ -28,8 +28,8 @@ class ConsoleApplication extends Application
{
private static $obj = null;
const VERSION_ID = 416;
const VERSION = "2.5.1";
const VERSION_ID = 417;
const VERSION = "2.5.2";
/**
* @throws InitException
@@ -43,6 +43,8 @@ class ConsoleApplication extends Application
}
/**
* @param string $with_default_cmd
* @return ConsoleApplication
* @throws InitException
*/
public function initEnv($with_default_cmd = ""): ConsoleApplication {

View File

@@ -6,9 +6,8 @@
namespace ZM\DB;
use Exception;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\MySQL\MySQLManager;
use ZM\Store\MySQL\SqlPoolStorage;
use PDOException;
use PDOStatement;
@@ -25,12 +24,12 @@ class DB
private static $table_list = [];
/**
* @param $db_name
* @throws DbException
* @throws Exception
*/
public static function initTableList() {
if (!extension_loaded("mysqlnd")) throw new Exception("Can not find mysqlnd PHP extension.");
$result = self::rawQuery("select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='" . ZMConfig::get("global", "sql_config")["sql_database"] . "';", []);
public static function initTableList($db_name) {
if (!extension_loaded("mysqlnd")) throw new DbException("Can not find mysqlnd PHP extension.");
$result = MySQLManager::getWrapper()->fetchAllAssociative("select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=?;", [$db_name]);
foreach ($result as $v) {
self::$table_list[] = $v['TABLE_NAME'];
}

View File

@@ -4,9 +4,11 @@
namespace ZM\Event;
use Closure;
use Doctrine\Common\Annotations\AnnotationException;
use Error;
use Exception;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\Exception\InterruptException;
use ZM\Store\LightCacheInside;
@@ -117,7 +119,7 @@ class EventDispatcher
public function dispatchEvent($v, $rule_func = null, ...$params) {
$q_c = $v->class;
$q_f = $v->method;
if ($q_c === "" && ($q_f instanceof \Closure)) {
if ($q_c === "" && ($q_f instanceof Closure)) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] 闭包函数的事件触发过程!");
if ($rule_func !== null && !$rule_func($v)) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] 闭包函数下的 ruleFunc 判断为 false, 拒绝执行此方法。");
@@ -137,11 +139,16 @@ class EventDispatcher
if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法下的 ruleFunc 为真,继续执行方法本身 ...");
if (isset(EventManager::$middleware_map[$q_c][$q_f])) {
$middlewares = EventManager::$middleware_map[$q_c][$q_f];
if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法还绑定了 Middleware" . implode(", ", array_map(function($x){ return $x->middleware; }, $middlewares)));
if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法还绑定了 Middleware" . implode(", ", array_map(function ($x) { return $x->middleware; }, $middlewares)));
$before_result = true;
$r = [];
foreach ($middlewares as $k => $middleware) {
if (!isset(EventManager::$middlewares[$middleware->middleware])) throw new AnnotationException("Annotation parse error: Unknown MiddlewareClass named \"{$middleware->middleware}\"!");
if (!isset(EventManager::$middlewares[$middleware->middleware])) {
if ((ZMConfig::get("global", "runtime")["middleware_error_policy"] ?? 1) == 1)
throw new AnnotationException("Annotation parse error: Unknown MiddlewareClass named \"{$middleware->middleware}\"!");
else
continue;
}
$middleware_obj = EventManager::$middlewares[$middleware->middleware];
$before = $middleware_obj["class"];
//var_dump($middleware_obj);
@@ -186,7 +193,8 @@ class EventDispatcher
}
throw $e;
}
for ($i = count($middlewares) - 1; $i >= 0; --$i) {
$cnts = count($middlewares) - 1;
for ($i = $cnts; $i >= 0; --$i) {
$middleware_obj = EventManager::$middlewares[$middlewares[$i]->middleware];
if (isset($middleware_obj["after"], $r[$i])) {
if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 存在后置事件,执行中 ...");

View File

@@ -32,6 +32,7 @@ class EventManager
self::$middlewares = $parser->getMiddlewares();
self::$middleware_map = $parser->getMiddlewareMap();
self::$req_mapping = $parser->getReqMapping();
$parser->verifyMiddlewares();
}
/**

View File

@@ -24,7 +24,7 @@ use ZM\Event\EventDispatcher;
use ZM\Event\EventManager;
use ZM\Event\SwooleEvent;
use ZM\Exception\DbException;
use ZM\Exception\ZMException;
use ZM\Exception\ZMKnownException;
use ZM\Framework;
use ZM\Module\QQBot;
use ZM\MySQL\MySQLPool;
@@ -32,6 +32,7 @@ use ZM\Store\LightCacheInside;
use ZM\Store\MySQL\SqlPoolStorage;
use ZM\Store\Redis\ZMRedisPool;
use ZM\Utils\DataProvider;
use ZM\Utils\Manager\ModuleManager;
use ZM\Utils\SignalListener;
/**
@@ -48,7 +49,6 @@ class OnWorkerStart implements SwooleEvent
}
unset(Context::$context[Coroutine::getCid()]);
if ($server->taskworker === false) {
zm_atomic("_#worker_" . $worker_id)->set($server->worker_pid);
if (LightCacheInside::get("wait_api", "wait_api") !== null) {
LightCacheInside::unset("wait_api", "wait_api");
@@ -144,14 +144,12 @@ class OnWorkerStart implements SwooleEvent
$parser->addRegisterPath(DataProvider::getSourceRootDir() . "/" . $v . "/", trim($k, "\\"));
}
}
$parser->registerMods();
EventManager::loadEventByParser($parser); //加载事件
//加载自定义的全局函数
Console::debug("Loading context class...");
$context_class = ZMConfig::get("global", "context_class");
if (!is_a($context_class, ContextInterface::class, true)) {
throw new ZMException(zm_internal_errcode("E00032") . "Context class must implemented from ContextInterface!");
throw new ZMKnownException("E00032", "Context class must implemented from ContextInterface!");
}
//加载插件
@@ -175,7 +173,21 @@ class OnWorkerStart implements SwooleEvent
}
}
//TODO: 编写加载外部插件的方式
// 检查是否允许热加载phar模块允许的话将遍历phar内的文件
$plugin_enable_hotload = ZMConfig::get("global", "module_loader")["enable_hotload"] ?? false;
if ($plugin_enable_hotload) {
$list = ModuleManager::getPackedModules();
foreach($list as $k => $v) {
if (\server()->worker_id === 0) Console::info("Loading packed module: ".$k);
require_once $v["phar-path"];
$func = "loader".$v["generated-id"];
$func();
$parser->addRegisterPath("phar://".$v["phar-path"]."/".$v["module-root-path"], $v["namespace"]);
}
}
$parser->registerMods();
EventManager::loadEventByParser($parser); //加载事件
}
private function initMySQLPool() {
@@ -233,7 +245,7 @@ class OnWorkerStart implements SwooleEvent
->withPassword($real_conf["password"])
->withOptions($real_conf["options"] ?? [PDO::ATTR_STRINGIFY_FETCHES => false])
);
DB::initTableList();
DB::initTableList($real_conf["dbname"]);
}
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace ZM\Exception;
class AnnotationException extends \Doctrine\Common\Annotations\AnnotationException
{
}

View File

@@ -6,9 +6,9 @@ namespace ZM\Exception;
use Throwable;
class DbException extends ZMException
class DbException extends ZMKnownException
{
public function __construct($message = "", $code = 0, Throwable $previous = null) {
parent::__construct(zm_internal_errcode("E00043") . $message, $code, $previous);
parent::__construct("E00043", $message, $code, $previous);
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace ZM\Exception;
use Throwable;
class LightCacheException extends ZMKnownException
{
public function __construct($err_code, $message = "", $code = 0, Throwable $previous = null) {
parent::__construct($err_code, $message, $code, $previous);
}
}

View File

@@ -6,7 +6,7 @@ namespace ZM\Exception;
use Exception;
class ZMException extends Exception
abstract class ZMException extends Exception
{
}

View File

@@ -0,0 +1,14 @@
<?php
namespace ZM\Exception;
use Throwable;
class ZMKnownException extends ZMException
{
public function __construct($err_code, $message = "", $code = 0, Throwable $previous = null) {
parent::__construct(zm_internal_errcode($err_code) . $message, $code, $previous);
}
}

View File

@@ -25,6 +25,33 @@ use ZM\Annotation\Swoole\SwooleHandler;
use ZM\Console\Console;
use ZM\Utils\Terminal;
use ZM\Utils\ZMUtil;
use function date_default_timezone_set, define;
use function exec;
use function explode;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function get_class;
use function get_included_files;
use function in_array;
use function intval;
use function is_array;
use function is_dir;
use function json_decode;
use function json_encode;
use function mkdir;
use function ob_get_clean;
use function ob_start;
use function posix_getpid;
use function str_pad;
use function strlen;
use function substr;
use function swoole_cpu_num;
use function trim;
use function uuidgen;
use function working_dir;
use function zm_atomic;
use function zm_internal_errcode;
class Framework
{
@@ -305,9 +332,7 @@ class Framework
$motd = file_get_contents(__DIR__ . "/../../config/motd.txt");
}
$motd = explode("\n", $motd);
foreach ($motd as $k => $v) {
$motd[$k] = substr($v, 0, $tty_width);
}
foreach ($motd as $k => $v) $motd[$k] = substr($v, 0, $tty_width);
$motd = implode("\n", $motd);
echo $motd;
}

View File

@@ -122,7 +122,13 @@ class ModulePacker
}
private function generatePharAutoload(): array {
return ZMUtil::getClassesPsr4($this->module['module-path'], $this->module['namespace'], null, true);
$pos = strpos($this->module['module-path'], DataProvider::getSourceRootDir().'/');
if ($pos === 0) {
$path_value = substr($this->module['module-path'], strlen(DataProvider::getSourceRootDir().'/'));
} else {
throw new ModulePackException(zm_internal_errcode("E99999")); //未定义的错误
}
return ZMUtil::getClassesPsr4($this->module['module-path'], $this->module['namespace'], null, $path_value);
}
private function getComposerAutoloadItems(): array {

View File

@@ -32,13 +32,14 @@ class ModuleUnpacker
* @param bool $override_light_cache
* @param bool $override_data_files
* @param bool $override_source
* @param bool $ignore_depends
* @return array
* @throws ModulePackException
* @throws ZMException
*/
public function unpack(bool $override_light_cache = false, bool $override_data_files = false, bool $override_source = false): array {
public function unpack(bool $override_light_cache = false, bool $override_data_files = false, bool $override_source = false, $ignore_depends = false): array {
$this->checkConfig();
$this->checkDepends();
$this->checkDepends($ignore_depends);
$this->checkLightCacheStore();
$this->checkZMDataStore();
@@ -62,18 +63,19 @@ class ModuleUnpacker
/**
* 检查模块依赖关系
* @param bool $ignore_depends
* @throws ModulePackException
* @throws ZMException
*/
private function checkDepends() {
private function checkDepends($ignore_depends = false) {
$configured = ModuleManager::getConfiguredModules();
$depends = $this->module_config["depends"] ?? [];
foreach ($depends as $k => $v) {
if (!isset($configured[$k])) {
if (!isset($configured[$k]) && !$ignore_depends) {
throw new ModulePackException(zm_internal_errcode("E00064") . "模块 " . $this->module_config["name"] . " 依赖的模块 $k 不存在");
}
$current_ver = $configured[$k]["version"] ?? "1.0";
if (!VersionComparator::compareVersionRange($current_ver, $v)) {
if (!VersionComparator::compareVersionRange($current_ver, $v) && !$ignore_depends) {
throw new ModulePackException(zm_internal_errcode("E00063") . "模块 " . $this->module_config["name"] . " 依赖的模块 $k 版本依赖不符合条件(现有版本: " . $current_ver . ", 需求版本: " . $v . "");
}
}

View File

@@ -21,12 +21,13 @@ class MySQLConnection implements Connection
private $conn;
public function __construct() {
Console::info("Constructing...");
Console::debug("Constructing...");
$this->conn = SqlPoolStorage::$sql_pool->getConnection();
}
public function prepare($sql, $options = []) {
try {
Console::debug("Running SQL prepare: ".$sql);
$statement = $this->conn->prepare($sql, $options);
assert(($statement instanceof PDOStatementProxy) || ($statement instanceof PDOStatement));
} catch (PDOException $exception) {
@@ -51,6 +52,7 @@ class MySQLConnection implements Connection
public function exec($sql) {
try {
Console::debug("Running SQL exec: ".$sql);
$statement = $this->conn->exec($sql);
assert($statement !== false);
return $statement;
@@ -88,7 +90,7 @@ class MySQLConnection implements Connection
}
public function __destruct() {
Console::info("Destructing");
Console::debug("Destructing");
SqlPoolStorage::$sql_pool->putConnection($this->conn);
}
}

View File

@@ -4,16 +4,16 @@
namespace ZM\MySQL;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver as DoctrineDriver;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Schema\MySqlSchemaManager;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
class MySQLDriver implements Driver
class MySQLDriver implements DoctrineDriver
{
public function connect(array $params, $username = null, $password = null, array $driverOptions = []) {
Console::info("Requiring new connection");
Console::debug("Requiring new connection");
return new MySQLConnection();
}

View File

@@ -4,17 +4,12 @@
namespace ZM\MySQL;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
class MySQLManager
{
/**
* @return Connection
* @throws Exception
* @return MySQLWrapper
*/
public static function getConnection() {
return DriverManager::getConnection(["driverClass" => MySQLDriver::class]);
public static function getWrapper(): MySQLWrapper {
return new MySQLWrapper();
}
}

View File

@@ -34,4 +34,8 @@ class MySQLPool extends PDOPool
$this->count--;
parent::put($connection);
}
public function getCount() {
return $this->count;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace ZM\MySQL;
use Doctrine\DBAL\Query\QueryBuilder;
use ZM\Exception\DbException;
class MySQLQueryBuilder extends QueryBuilder
{
private $wrapper;
public function __construct(MySQLWrapper $wrapper) {
parent::__construct($wrapper->getConnection());
$this->wrapper = $wrapper;
}
/**
* @return int|MySQLStatementWrapper
* @throws DbException
*/
public function execute() {
if ($this->getType() === self::SELECT) {
return $this->wrapper->executeQuery($this->getSQL(), $this->getParameters(), $this->getParameterTypes());
}
return $this->wrapper->executeStatement($this->getSQL(), $this->getParameters(), $this->getParameterTypes());
}
}

View File

@@ -29,7 +29,14 @@ class MySQLStatement implements Statement, \IteratorAggregate
}
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = []) {
return $this->statement->setFetchMode($fetchMode, $arg2, $arg3);
if ($arg2 !== null && $arg3 !== [])
return $this->statement->setFetchMode($fetchMode, $arg2, $arg3);
elseif ($arg2 !== null && $arg3 === [])
return $this->statement->setFetchMode($fetchMode, $arg2);
elseif ($arg2 === null && $arg3 !== [])
return $this->statement->setFetchMode($fetchMode, $arg2, $arg3);
else
return $this->statement->setFetchMode($fetchMode);
}
public function fetch($fetchMode = PDO::FETCH_ASSOC, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) {

View File

@@ -0,0 +1,232 @@
<?php
/**
* @noinspection PhpMissingReturnTypeInspection
* @noinspection PhpUnused
*/
namespace ZM\MySQL;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\ForwardCompatibility\Result;
use Throwable;
use Traversable;
use ZM\Exception\DbException;
class MySQLStatementWrapper
{
public $stmt;
public function __construct(?Result $stmt) {
$this->stmt = $stmt;
}
/**
* 获取结果的迭代器
* wrapper method
* @return ResultStatement
*/
public function getIterator() {
return $this->stmt->getIterator();
}
/**
* 获取列数
* wrapper method
* @return int
*/
public function columnCount() {
return $this->stmt->columnCount();
}
/**
* wrapper method
* @return array|false|mixed
* @throws DbException
*/
public function fetchNumeric() {
try {
return $this->stmt->fetchNumeric();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return array|false|mixed
* @throws DbException
*/
public function fetchAssociative() {
try {
return $this->stmt->fetchAssociative();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return false|mixed
* @throws DbException
*/
public function fetchOne() {
try {
return $this->stmt->fetchOne();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return array
* @throws DbException
*/
public function fetchAllNumeric(): array {
try {
return $this->stmt->fetchAllNumeric();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return array
* @throws DbException
*/
public function fetchAllAssociative(): array {
try {
return $this->stmt->fetchAllAssociative();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return array
* @throws DbException
*/
public function fetchAllKeyValue(): array {
try {
return $this->stmt->fetchAllKeyValue();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return array
* @throws DbException
*/
public function fetchAllAssociativeIndexed(): array {
try {
return $this->stmt->fetchAllAssociativeIndexed();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return array
* @throws DbException
*/
public function fetchFirstColumn(): array {
try {
return $this->stmt->fetchFirstColumn();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return Traversable
* @throws DbException
*/
public function iterateNumeric(): Traversable {
try {
return $this->stmt->iterateNumeric();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return Traversable
* @throws DbException
*/
public function iterateAssociative(): Traversable {
try {
return $this->stmt->iterateAssociative();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return Traversable
* @throws DbException
*/
public function iterateKeyValue(): Traversable {
try {
return $this->stmt->iterateKeyValue();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return Traversable
* @throws DbException
*/
public function iterateAssociativeIndexed(): Traversable {
try {
return $this->stmt->iterateAssociativeIndexed();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return Traversable
* @throws DbException
*/
public function iterateColumn(): Traversable {
try {
return $this->stmt->iterateColumn();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return int
* @throws DbException
*/
public function rowCount() {
try {
return $this->stmt->rowCount();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
*/
public function free(): void {
$this->stmt->free();
}
}

View File

@@ -1,15 +1,575 @@
<?php
/**
* @noinspection PhpUnused
*/
namespace ZM\MySQL;
use Closure;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\ParameterType;
use Throwable;
use Traversable;
use ZM\Exception\DbException;
class MySQLWrapper
{
public $connection;
private $connection;
/**
* MySQLWrapper constructor.
* @throws DbException
*/
public function __construct() {
$this->connection = MySQLManager::getConnection();
try {
$this->connection = DriverManager::getConnection(["driverClass" => MySQLDriver::class]);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return string
*/
public function getDatabase(): string {
return $this->connection->getDatabase();
}
/**
* wrapper method
* @return bool
*/
public function isAutoCommit(): bool {
return $this->connection->isAutoCommit();
}
/**
* wrapper method
* @param $autoCommit
*/
public function setAutoCommit($autoCommit) {
$this->connection->setAutoCommit($autoCommit);
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array|false
* @throws DbException
*/
public function fetchAssociative(string $query, array $params = [], array $types = []) {
try {
return $this->connection->fetchAssociative($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array|false
* @throws DbException
*/
public function fetchNumeric(string $query, array $params = [], array $types = []) {
try {
return $this->connection->fetchNumeric($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* @param string $query
* @param array $params
* @param array $types
* @return false|mixed
* @throws DbException
*/
public function fetchOne(string $query, array $params = [], array $types = []): bool {
try {
return $this->connection->fetchOne($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return bool
*/
public function isTransactionActive(): bool {
return $this->connection->isTransactionActive();
}
/**
* @param $table
* @param array $criteria
* @param array $types
* @return int
* @throws DbException
*/
public function delete($table, array $criteria, array $types = []): int {
try {
return $this->connection->delete($table, $criteria, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $level
* @return int
*/
public function setTransactionIsolation($level): int {
return $this->connection->setTransactionIsolation($level);
}
/**
* wrapper method
* @return int|null
*/
public function getTransactionIsolation(): ?int {
return $this->connection->getTransactionIsolation();
}
/**
* wrapper method
* @param $table
* @param array $data
* @param array $criteria
* @param array $types
* @return int
* @throws DbException
*/
public function update($table, array $data, array $criteria, array $types = []): int {
try {
return $this->connection->update($table, $data, $criteria, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $table
* @param array $data
* @param array $types
* @return int
* @throws DbException
*/
public function insert($table, array $data, array $types = []): int {
try {
return $this->connection->insert($table, $data, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $str
* @return string
*/
public function quoteIdentifier($str): string {
return $this->connection->quoteIdentifier($str);
}
/**
* wrapper method
* @param $value
* @param int $type
* @return mixed
*/
public function quote($value, $type = ParameterType::STRING) {
return $this->connection->quote($value, $type);
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array
* @throws DbException
*/
public function fetchAllNumeric(string $query, array $params = [], array $types = []): array {
try {
return $this->connection->fetchAllNumeric($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array
* @throws DbException
*/
public function fetchAllAssociative(string $query, array $params = [], array $types = []): array {
try {
return $this->connection->fetchAllAssociative($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array
* @throws DbException
*/
public function fetchAllKeyValue(string $query, array $params = [], array $types = []): array {
try {
return $this->connection->fetchAllKeyValue($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array
* @throws DbException
*/
public function fetchAllAssociativeIndexed(string $query, array $params = [], array $types = []): array {
try {
return $this->connection->fetchAllAssociativeIndexed($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return array
* @throws DbException
*/
public function fetchFirstColumn(string $query, array $params = [], array $types = []): array {
try {
return $this->connection->fetchFirstColumn($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return Traversable
* @throws DbException
*/
public function iterateNumeric(string $query, array $params = [], array $types = []): Traversable {
try {
return $this->connection->iterateNumeric($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return Traversable
* @throws DbException
*/
public function iterateAssociative(string $query, array $params = [], array $types = []): Traversable {
try {
return $this->connection->iterateAssociative($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return Traversable
* @throws DbException
*/
public function iterateKeyValue(string $query, array $params = [], array $types = []): Traversable {
try {
return $this->connection->iterateKeyValue($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return Traversable
* @throws DbException
*/
public function iterateAssociativeIndexed(string $query, array $params = [], array $types = []): Traversable {
try {
return $this->connection->iterateAssociativeIndexed($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param string $query
* @param array $params
* @param array $types
* @return Traversable
* @throws DbException
*/
public function iterateColumn(string $query, array $params = [], array $types = []): Traversable {
try {
return $this->connection->iterateColumn($query, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $sql
* @param array $params
* @param array $types
* @param QueryCacheProfile|null $qcp
* @return MySQLStatementWrapper
* @throws DbException
*/
public function executeQuery($sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): MySQLStatementWrapper {
try {
$query = $this->connection->executeQuery($sql, $params, $types, $qcp);
return new MySQLStatementWrapper($query);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $sql
* @param $params
* @param $types
* @param QueryCacheProfile $qcp
* @return MySQLStatementWrapper
* @throws DbException
*/
public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp): MySQLStatementWrapper {
try {
$query = $this->connection->executeCacheQuery($sql, $params, $types, $qcp);
return new MySQLStatementWrapper($query);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $sql
* @param array $params
* @param array $types
* @return int
* @throws DbException
*/
public function executeStatement($sql, array $params = [], array $types = []): int {
try {
return $this->connection->executeStatement($sql, $params, $types);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return int
*/
public function getTransactionNestingLevel(): int {
return $this->connection->getTransactionNestingLevel();
}
/**
* wrapper method
* @param null $name
* @return string
*/
public function lastInsertId($name = null): string {
return $this->connection->lastInsertId($name);
}
/**
* overwrite method to $this->connection->transactional()
* @param Closure $func
* @return mixed
* @throws DbException
*/
public function transactional(Closure $func) {
$this->beginTransaction();
try {
$res = $func($this);
$this->commit();
return $res;
} catch (Throwable $e) {
$this->rollBack();
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $nestTransactionsWithSavepoints
* @throws DbException
*/
public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints) {
try {
$this->connection->setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return bool
*/
public function getNestTransactionsWithSavepoints(): bool {
return $this->connection->getNestTransactionsWithSavepoints();
}
/**
* wrapper method
* @return bool
*/
public function beginTransaction(): bool {
return $this->connection->beginTransaction();
}
/**
* wrapper method
* @return bool
* @throws DbException
*/
public function commit(): bool {
try {
return $this->connection->commit();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return bool
* @throws DbException
*/
public function rollBack(): bool {
try {
return $this->connection->rollBack();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $savepoint
* @throws DbException
*/
public function createSavepoint($savepoint) {
try {
$this->connection->createSavepoint($savepoint);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $savepoint
* @throws DbException
*/
public function releaseSavepoint($savepoint) {
try {
$this->connection->releaseSavepoint($savepoint);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @param $savepoint
* @throws DbException
*/
public function rollbackSavepoint($savepoint) {
try {
$this->connection->rollbackSavepoint($savepoint);
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @throws DbException
*/
public function setRollbackOnly() {
try {
$this->connection->setRollbackOnly();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* wrapper method
* @return bool
* @throws DbException
*/
public function isRollbackOnly(): bool {
try {
return $this->connection->isRollbackOnly();
} catch (Throwable $e) {
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* overwrite method to $this->connection->createQueryBuilder
* @return MySQLQueryBuilder
*/
public function createQueryBuilder(): MySQLQueryBuilder {
return new MySQLQueryBuilder($this);
}
public function getConnection(): Connection {
return $this->connection;
}
public function __destruct() {

View File

@@ -9,6 +9,7 @@ use Swoole\Table;
use ZM\Annotation\Swoole\OnSave;
use ZM\Console\Console;
use ZM\Event\EventDispatcher;
use ZM\Exception\LightCacheException;
use ZM\Exception\ZMException;
use ZM\Framework;
use ZM\Utils\Manager\ProcessManager;
@@ -86,7 +87,7 @@ class LightCache
* @throws ZMException
*/
public static function get(string $key) {
if (self::$kv_table === null) throw new ZMException(zm_internal_errcode("E00048") . "not initialized LightCache");
if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache");
self::checkExpire($key);
$r = self::$kv_table->get($key);
return $r === false ? null : self::parseGet($r);
@@ -98,7 +99,7 @@ class LightCache
* @throws ZMException
*/
public static function getExpire(string $key) {
if (self::$kv_table === null) throw new ZMException(zm_internal_errcode("E00048") . "not initialized LightCache");
if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache");
self::checkExpire($key);
$r = self::$kv_table->get($key, "expire");
return $r === false ? null : $r - time();
@@ -111,7 +112,7 @@ class LightCache
* @since 2.4.3
*/
public static function getExpireTS(string $key) {
if (self::$kv_table === null) throw new ZMException(zm_internal_errcode("E00048") . "not initialized LightCache");
if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache");
self::checkExpire($key);
$r = self::$kv_table->get($key, "expire");
return $r === false ? null : $r;
@@ -125,7 +126,7 @@ class LightCache
* @throws ZMException
*/
public static function set(string $key, $value, int $expire = -1) {
if (self::$kv_table === null) throw new ZMException(zm_internal_errcode("E00048") . "not initialized LightCache");
if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache");
if (is_array($value)) {
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
if (strlen($value) >= self::$config["max_strlen"]) return false;
@@ -138,7 +139,7 @@ class LightCache
$data_type = "bool";
$value = json_encode($value);
} else {
throw new ZMException(zm_internal_errcode("E00049") . "Only can set string, array and int");
throw new LightCacheException("E00049", "Only can set string, array and int");
}
try {
return self::$kv_table->set($key, [
@@ -158,7 +159,7 @@ class LightCache
* @throws ZMException
*/
public static function update(string $key, $value) {
if (self::$kv_table === null) throw new ZMException(zm_internal_errcode("E00048") . "not initialized LightCache.");
if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache.");
if (is_array($value)) {
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
if (strlen($value) >= self::$config["max_strlen"]) return false;
@@ -168,7 +169,7 @@ class LightCache
} elseif (is_int($value)) {
$data_type = "int";
} else {
throw new ZMException(zm_internal_errcode("E00048") . "Only can set string, array and int");
throw new LightCacheException("E00048", "Only can set string, array and int");
}
try {
if (self::$kv_table->get($key) === false) return false;

View File

@@ -6,6 +6,7 @@ namespace ZM\Store;
use Exception;
use Swoole\Table;
use ZM\Exception\LightCacheException;
use ZM\Exception\ZMException;
class LightCacheInside
@@ -67,6 +68,6 @@ class LightCacheInside
self::$kv_table[$name] = new Table($size, $conflict_proportion);
self::$kv_table[$name]->column("value", Table::TYPE_STRING, $str_size);
$r = self::$kv_table[$name]->create();
if ($r === false) throw new ZMException(zm_internal_errcode("E00050") . "内存不足,创建静态表失败!");
if ($r === false) throw new LightCacheException("E00050", "内存不足,创建静态表失败!");
}
}

0
src/ZM/Store/ZMBuf.php Executable file → Normal file
View File

View File

@@ -4,9 +4,11 @@
namespace ZM\Utils\Manager;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\Exception\ModulePackException;
use ZM\Exception\ZMException;
use ZM\Exception\ZMKnownException;
use ZM\Module\ModulePacker;
use ZM\Module\ModuleUnpacker;
use ZM\Utils\DataProvider;
@@ -36,12 +38,12 @@ class ModuleManager
if ($json === null) continue;
if (!isset($json["name"])) continue;
if ($pathinfo["dirname"] == ".") {
throw new ZMException(zm_internal_errcode("E00052") . "在/src/目录下不可以直接标记为模块(zm.json),因为命名空间不能为根空间!");
throw new ZMKnownException("E00052", "在/src/目录下不可以直接标记为模块(zm.json),因为命名空间不能为根空间!");
}
$json["module-path"] = realpath($dir . "/" . $pathinfo["dirname"]);
$json["namespace"] = str_replace("/", "\\", $pathinfo["dirname"]);
if (isset($modules[$json["name"]])) {
throw new ZMException(zm_internal_errcode("E00053") . "重名模块:" . $json["name"]);
throw new ZMKnownException("E00053", "重名模块:" . $json["name"]);
}
$modules[$json["name"]] = $json;
}
@@ -50,7 +52,7 @@ class ModuleManager
}
public static function getPackedModules(): array {
$dir = DataProvider::getDataFolder() . "modules";
$dir = ZMConfig::get("global", "module_loader")["load_path"] ?? (ZM_DATA . "modules");
$ls = DataProvider::scanDirFiles($dir, true, false);
if ($ls === false) return [];
$modules = [];
@@ -88,7 +90,10 @@ class ModuleManager
public static function packModule($module): bool {
try {
$packer = new ModulePacker($module);
$packer->setOutputPath(DataProvider::getDataFolder() . "output");
if (!is_dir(DataProvider::getDataFolder())) throw new ModulePackException(zm_internal_errcode("E00070") . "zm_data dir not found!");
$path = realpath(DataProvider::getDataFolder() . "/output");
if ($path === false) mkdir($path = DataProvider::getDataFolder() . "/output");
$packer->setOutputPath($path);
$packer->setOverride();
$packer->pack();
return true;
@@ -107,7 +112,7 @@ class ModuleManager
public static function unpackModule($module, array $options = []) {
try {
$packer = new ModuleUnpacker($module);
return $packer->unpack((bool)$options["override-light-cache"], (bool)$options["override-zm-data"], (bool)$options["override-source"]);
return $packer->unpack((bool)$options["overwrite-light-cache"], (bool)$options["overwrite-zm-data"], (bool)$options["overwrite-source"], (bool)$options["ignore-depends"]);
} catch (ZMException $e) {
Console::error($e->getMessage());
return false;

View File

@@ -11,6 +11,17 @@ use ZM\Framework;
use ZM\Store\Lock\SpinLock;
use ZM\Store\ZMAtomic;
use ZM\Store\ZMBuf;
use function file_get_contents;
use function get_included_files;
use function is_callable;
use function is_string;
use function json_decode;
use function mb_substr;
use function md5_file;
use function pathinfo;
use function server;
use function str_replace;
use function substr;
class ZMUtil
{
@@ -45,15 +56,15 @@ class ZMUtil
* 在工作进程中返回可以通过reload重新加载的php文件列表
* @return string[]|string[][]
*/
public static function getReloadableFiles() {
return array_map(
function ($x) {
return str_replace(DataProvider::getSourceRootDir() . '/', '', $x);
}, array_diff(
get_included_files(),
Framework::$loaded_files
)
);
public static function getReloadableFiles(): array {
$array_map = [];
foreach (array_diff(
get_included_files(),
Framework::$loaded_files
) as $key => $x) {
$array_map[$key] = str_replace(DataProvider::getSourceRootDir() . '/', '', $x);
}
return $array_map;
}
/**
@@ -61,10 +72,10 @@ class ZMUtil
* @param $dir
* @param $base_namespace
* @param null|mixed $rule
* @param bool $return_kv
* @param bool $return_path_value
* @return String[]
*/
public static function getClassesPsr4($dir, $base_namespace, $rule = null, $return_kv = false) {
public static function getClassesPsr4($dir, $base_namespace, $rule = null, $return_path_value = false): array {
// 预先读取下composer的file列表
$composer = json_decode(file_get_contents(DataProvider::getSourceRootDir() . '/composer.json'), true);
$classes = [];
@@ -72,7 +83,7 @@ class ZMUtil
$files = DataProvider::scanDirFiles($dir, true, true);
foreach ($files as $v) {
$pathinfo = pathinfo($v);
if ($pathinfo['extension'] == 'php') {
if (($pathinfo['extension'] ?? '') == 'php') {
if ($rule === null) { //规则未设置回调时候,使用默认的识别过滤规则
if (substr(file_get_contents($dir . '/' . $v), 6, 6) == '#plain') continue;
elseif (mb_substr($v, 0, 7) == 'global_' || mb_substr($v, 0, 7) == 'script_') continue;
@@ -82,7 +93,7 @@ class ZMUtil
} elseif (is_callable($rule) && !($rule($dir, $pathinfo))) continue;
$dirname = $pathinfo['dirname'] == '.' ? '' : (str_replace('/', '\\', $pathinfo['dirname']) . '\\');
$class_name = $base_namespace . '\\' . $dirname . $pathinfo['filename'];
if ($return_kv) $classes[$class_name] = $v;
if (is_string($return_path_value)) $classes[$class_name] = $return_path_value . "/" .$v;
else $classes[] = $class_name;
}
}

View File

@@ -7,5 +7,4 @@ function loader__generated_id__() {
}
}
echo "OK!\n";
return json_decode(file_get_contents(__DIR__.'/zmplugin.json'), true) ?? ['zm_module' => false];