get(StdoutLogger::class); $logger->println($data); } } if (!function_exists('application')) { /** * @param Kernel $Kernel * @return Application */ function application(Kernel $Kernel): Application { $application = Kiri::getDi()->get(Application::class); $application->commands($Kernel); return $application; } } if (!function_exists('task')) { /** * @param string $handler * @param mixed $data * @param int $dstWorkerId * @param callable|null $finishFinishCallback * @return void * @throws Exception */ function task(string $handler, mixed $data, int $dstWorkerId = -1, ?callable $finishFinishCallback = null): void { $execute = Kiri::getDi()->get(TaskExecute::class); $execute->task($handler, $data, $dstWorkerId, $finishFinishCallback); } } if (!function_exists('taskWait')) { /** * @param string $handler * @param mixed $data * @param float $timeout * @param int $dstWorkerId * @return mixed * @throws Exception */ function taskWait(string $handler, mixed $data, float $timeout = 0.5, int $dstWorkerId = -1): mixed { $execute = Kiri::getDi()->get(TaskExecute::class); return $execute->taskWait($handler, $data, $timeout, $dstWorkerId); } } if (!function_exists('taskCo')) { /** * @param array $tasks * @param float $timeout * @return false|array */ function taskCo(array $tasks, float $timeout = 0.5): false|array { $execute = Kiri::getDi()->get(TaskExecute::class); return $execute->taskCo($tasks, $timeout); } } if (!function_exists('taskWaitMulti')) { /** * @param array $tasks * @param float $timeout * @return false|array */ function taskWaitMulti(array $tasks, float $timeout = 0.5): false|array { $execute = Kiri::getDi()->get(TaskExecute::class); return $execute->taskWaitMulti($tasks, $timeout); } } if (!function_exists('make')) { /** * @param $name * @param $default * @return mixed * @throws */ function make($name, $default = NULL): mixed { if (!class_exists($name) && !interface_exists($name)) { return Kiri::getDi()->get($default); } return Kiri::getDi()->get($name); } } if (!function_exists('isJson')) { function isJson(?string $string): bool { if (is_null($string)) return false; return (str_starts_with($string, '{') && str_ends_with($string, '}')) || (str_ends_with($string, '[') && str_starts_with($string, ']')); } } if (!function_exists('instance')) { /** * @param $class * @param array $constrict * @param array $config * @return null|object * @throws */ function instance($class, array $constrict = [], array $config = []): ?object { return Kiri::getDi()->make($class, $constrict, $config); } } if (!function_exists('call')) { /** * @param $handler * @param mixed ...$params * @return mixed * @throws */ function call($handler, ...$params): mixed { if (is_array($handler) && is_string($handler[0])) { $handler[0] = di($handler[0]); } if (!is_callable($handler, true)) { throw new Exception('Call function not exists.'); } return call_user_func($handler, ...$params); } } if (!function_exists('checkPortIsAlready')) { /** * @param $port * @return bool|string */ function checkPortIsAlready($port): bool|string { $port = (int)$port; if ($port <= 0) { return FALSE; } if (!Kiri::getPlatform()->isLinux()) { exec("lsof -i :" . $port . " | grep -i 'LISTEN' | awk '{print $2}'", $output); if (empty($output)) { return FALSE; } $output = explode(PHP_EOL, $output[0]); return $output[0]; } exec('netstat -lnp 2>/dev/null | grep :' . $port . ' | grep "LISTEN" | awk \'{print $7}\'', $output); if (empty($output)) { exec('ss -ltnp 2>/dev/null | grep :' . $port . ' | sed -n \"s/.*pid=\\([0-9]*\\).*/\\1/p\"', $output); } if (empty($output)) { return FALSE; } $pid = trim((string)$output[0]); if (str_contains($pid, '/')) { $pid = explode('/', $pid)[0]; } return $pid !== '' ? $pid : FALSE; } } if (!function_exists('set_env')) { /** * @param $key * @param $value */ function set_env($key, $value): void { putenv(sprintf('%s=%s', $key, $value)); } } if (!function_exists('enable_file_modification_listening')) { function enable_file_modification_listening(): void { putenv('enable_file_modification_listening=on'); } } if (!function_exists('is_enable_file_modification_listening')) { /** * @return bool */ #[Pure] function is_enable_file_modification_listening(): bool { return env('enable_file_modification_listening', 'off') == 'on'; } } if (!function_exists('disable_file_modification_listening')) { function disable_file_modification_listening(): void { putenv('enable_file_modification_listening=off'); } } if (!function_exists('now')) { /** * @return string */ function now(): string { return date('Y-m-d H:i:s') . '.' . str_replace(time() . '.', '', (string)microtime(TRUE)); } } if (!function_exists('directory')) { /** * @param $name * @return string */ function directory($name): string { return realpath(APP_PATH . $name); } } if (!function_exists('msgpack_pack')) { /** * @param $content * @return string */ function msgpack_pack($content): string { return serialize($content); } } if (!function_exists('msgpack_unpack')) { /** * @param $content * @return mixed */ function msgpack_unpack($content): mixed { return unserialize($content); } } if (!function_exists('request')) { /** * @return Request * @throws */ function request(): RequestInterface { $request = Kiri::getDi()->get(RequestInterface::class); return Context::get(RequestInterface::class, $request); } } if (!function_exists('inject')) { /** * @param object $object * @return object * @throws */ function inject(object $object): object { $container = Kiri::getDi(); $reflect = $container->getReflectionClass($object::class); $container->resolveProperties($reflect, $object); return $object; } } if (!function_exists('response')) { /** * @return Response * @throws */ function response(): ResponseInterface { $data = Kiri::getDi()->get(ResponseInterface::class); return Context::get(ResponseInterface::class, $data); } } if (!function_exists('redis')) { /** * @return \Kiri\NoSql\Redis|Redis * @throws */ function redis(): \Kiri\NoSql\Redis|Redis { return Kiri::getDi()->get(\Kiri\NoSql\Redis::class); } } if (!function_exists('fire')) { /** * @param object $event * @throws */ function fire(object $event): void { di(EventDispatch::class)->dispatch($event); } } if (!function_exists('trim_blank')) { /** * 空白字符替换 * @param string $content 内容 * @param int $len 截取长度 * @param string $encode 编码 * @param bool $htmlTags * @return array|string|null */ function trim_blank(string $content, int $len = 0, string $encode = 'utf-8', bool $htmlTags = TRUE): array|string|null { $str = trim($content); if ($htmlTags) { $str = strip_tags($str); } $str = preg_replace('/[\n|\r|\t]+/', '', $str); $str = preg_replace("/(\s|\ \;| |\xc2\xa0)/", '', $str); if ($len > 0) { return mb_substr($str, 0, $len, $encode); } else { return $str; } } } if (!function_exists('storage')) { /** * @param string|null $fileName * @param string|null $path * @return string * @throws */ function storage(?string $fileName = '', ?string $path = ''): string { if (!str_ends_with($path, '/')) { $path .= '/'; } $basePath = rtrim(Kiri::getStoragePath(), '/'); if (!empty($path)) { $path = ltrim($path, '/'); if (!is_dir($basePath . '/' . $path)) { mkdir($basePath . '/' . $path, 0777, TRUE); } } if (empty($fileName)) { return $basePath . '/' . $path; } $fileName = $basePath . '/' . $path . $fileName; if (!file_exists($fileName)) { touch($fileName); } return $fileName; } } if (!function_exists('on')) { /** * @param $name * @param $callback * @param int $index * @throws */ function on($name, $callback, int $index = 0): void { $pro = di(EventProvider::class); $pro->on($name, $callback, $index); } } if (!function_exists('off')) { /** * @param $name * @param $callback * @throws */ function off($name, $callback): void { $pro = di(EventProvider::class); $pro->off($name, $callback); } } if (!function_exists('process_name_set')) { /** * @param int $pid * @param string|null $prefix * @throws */ function process_name_set(int $pid, ?string $prefix = NULL): void { if (Kiri::getPlatform()->isMac()) { return; } $name = \config('site.id', 'system') . '[' . $pid . ']'; if (!empty($prefix)) { $name .= '.' . $prefix; } swoole_set_process_name($name); } } if (!function_exists('zero_full')) { /** * @param int $data * @param int $length * @return string */ function zero_full(int $data = 1, int $length = 10): string { return sprintf('%0' . $length . 'd', $data); } } if (!function_exists('env')) { /** * @param $key * @param null $default * @return array|string|null */ function env($key, $default = NULL): null|array|string { $env = getenv($key); if ($env === FALSE) { return $default; } return $env; } } if (!function_exists('config')) { /** * @param $key * @param null $default * @return mixed */ function config($key, mixed $default = NULL): mixed { return make(ConfigProvider::class)->get($key, $default); } } if (!function_exists('created')) { /** * @param $key * @param array $construct * @param array $config * @return null|object * @throws */ function created($key, array $construct = [], array $config = []): ?object { return Kiri::getDi()->make($key, $construct, $config); } } if (!function_exists('di')) { /** * @param string|object $className * @return mixed * @throws */ function di(string|object $className): mixed { if (is_object($className)) { return $className; } return Kiri::getDi()->get($className); } } if (!function_exists('sweep')) { /** * @param string $configPath * @return array */ function sweep(string $configPath = APP_PATH . 'config'): array { $array = []; // 检查目录是否存在 if (!is_dir($configPath)) { throw new InvalidArgumentException("Config directory does not exist: {$configPath}"); } // 获取所有PHP配置文件 $configFiles = glob($configPath . '/*.php'); foreach ($configFiles as $config) { // 使用 pathinfo 更安全地获取文件名 $filename = pathinfo($config, PATHINFO_FILENAME); $key = strtolower($filename); // 验证文件是否可读 if (!is_readable($config)) { throw new RuntimeException("Cannot read config file: {$config}"); } // 使用 include 而不是 require_once,这样不会跳过已加载的文件 // 在配置加载场景中,通常希望每次都重新加载 $configData = require_once $config; if (!is_array($configData)) { continue; } $array[$key] = $configData; } return $array; } } if (!function_exists('merge')) { /** * @param $param * @param $param1 * @return array */ function merge($param, $param1): array { return ArrayAccess::merge($param, $param1); } } if (!function_exists('event')) { /** * @param object $object * @return void * @throws */ function event(object $object): void { Kiri::getDi()->get(EventDispatch::class)->dispatch($object); } } if (!function_exists('throwable')) { /** * 错误格式化 * @param Throwable|Error|string $throwable * @return string */ function throwable(\Throwable|\Error|string $throwable): string { if (is_string($throwable)) { return $throwable; } $message = $throwable::class . ' ' . $throwable->getMessage() . PHP_EOL; $message .= ' File: ' . $throwable->getFile() . PHP_EOL; $message .= ' Line: ' . $throwable->getLine() . PHP_EOL; $file = $throwable->getFile(); $line = $throwable->getLine(); $trance = $throwable->getTrace(); $current = array_shift($trance); if (!isset($current['file'])) { $current['file'] = $file; } if (!isset($current['line'])) { $current['line'] = $line; } $message .= ' Trance: ' . $current['file'] . ' -> ' . (isset($current['class']) ? $current['class'] . '::' : '') . ($current['function'] ?? 'Closure') . ' line ' . $current['line'] . PHP_EOL; foreach ($trance as $value) { if (!isset($value['file'])) { $value['file'] = $file; } if (!isset($value['line'])) { $value['line'] = $line; } $file = $value['file']; $line = $value['line']; $message .= ' ' . $value['file'] . ' -> ' . (isset($value['class']) ? $value['class'] . '::' : '') . ($value['function'] ?? 'Closure') . ' line ' . $line . PHP_EOL; } return $message; } } if (!function_exists('json_log')) { function json_log(Throwable $throwable, array $data = []): void { $param = []; $param['time'] = date('Y-m-d H:i:s'); $param['request'] = [ 'path' => \request()->getUri()->getPath(), 'headers' => \request()->getHeaders(), 'method' => \request()->getMethod(), 'params' => \request()->getBody()->getContents(), ]; $param['exception'] = [ 'message' => $throwable->getMessage(), 'code' => $throwable->getCode(), 'file' => $throwable->getFile(), 'line' => $throwable->getLine(), 'trace' => $throwable->getTrace(), ]; $param['data'] = $data; file_put_contents(storage('exception-' . date('Y-m-d') . '.log', 'exception'), json_encode($param, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND); } } if (!function_exists('map')) { /** * @param array $map * @param Closure $closure * @return void */ function map(array $map, Closure $closure): void { foreach ($map as $key => $value) { $closure($key, $value); } } }