Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions src/AutoReload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

declare(strict_types=1);
/**
* This file is part of Simps.
*
* @link https://simps.io
* @document https://doc.simps.io
* @license https://github.com/simple-swoole/simps/blob/master/LICENSE
*/
namespace Simps\Utils;

use Swoole\Process;
use Swoole\Server;
use Swoole\Timer;

/**
* 'process' => [
* [\Simps\Utils\AutoReload::class, 'start'],
* ],
* Class AutoReload.
*/
class AutoReload
{
/**
* @var Server
*/
protected $server;

/**
* @var Process
*/
protected $hotReloadProcess;

/**
* 文件类型.
* @var array
*/
protected $reloadFileTypes = ['.php' => true];

/**
* 监听文件.
* @var array
*/
protected $lastFileList = [];

/**
* 是否正在重载.
* @var bool
*/
protected $reloading = false;

/**
* AutoReload constructor.
*/
public function __construct(Server $server)
{
$this->server = $server;
}

/**
* start.
* @return Process
*/
public static function start(Server $server)
{
$autoLoad = new self($server);

$autoLoad->hotReloadProcess = new Process([$autoLoad, 'hotReloadProcessCallBack'], false, 2, false);

return $autoLoad->hotReloadProcess;
}

/**
* hotReloadProcessCallBack.
*/
public function hotReloadProcessCallBack(Process $worker)
{
$this->hotReloadProcess->signal(SIGUSR1, [$this, 'signalCallBack']);

$this->run(BASE_PATH);

$currentOS = PHP_OS;

$currentPID = $this->hotReloadProcess->pid;

echoSuccess("自动重载代码初始化({$currentOS})PID: {$currentPID} ...");
}

public function signalCallBack()
{
echoSuccess('重载时间: ' . date('Y-m-d H:i:s'));

$res = $this->server->reload();

$res ? echoSuccess('重载成功') : echoError('重载失败');
}

/**
* 添加文件类型
* addFileType.
* @param $type
* @return $this
*/
public function addFileType($type)
{
$type = trim($type, '.');

$this->reloadFileTypes['.' . $type] = true;

return $this;
}

/**
* watch.
* @param $dir
*/
public function watch($dir)
{
$files = FileHelper::scanDirectory($dir);

$dirtyList = [];

foreach ($files as $file) {
//检测文件类型
$fileType = strrchr($file, '.');
if (isset($this->reloadFileTypes[$fileType])) {
$fileInfo = new \SplFileInfo($file);
$mtime = $fileInfo->getMTime();
$inode = $fileInfo->getInode();
$dirtyList[$inode] = $mtime;
}
}

// 当数组中出现脏值则发生了文件变更
if (array_diff_assoc($dirtyList, $this->lastFileList)) {
$this->lastFileList = $dirtyList;
if ($this->reloading) {
$this->sendReloadSignal();
}
}

$this->reloading = true;
}

/**
* run.
* @param mixed $dir
*/
public function run($dir)
{
$this->watch($dir);

Timer::tick(1000, function () use ($dir) {
$this->watch($dir);
});
}

/**
* sendReloadSignal.
*/
protected function sendReloadSignal()
{
Process::kill($this->hotReloadProcess->pid, SIGUSR1);
}
}
203 changes: 203 additions & 0 deletions src/FileHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<?php

declare(strict_types=1);
/**
* This file is part of Simps.
*
* @link https://simps.io
* @document https://doc.simps.io
* @license https://github.com/simple-swoole/simps/blob/master/LICENSE
*/
namespace Simps\Utils;

class FileHelper
{
/**
* 检测目录并循环创建目录
* mkdir.
* @param $catalogue
* @return bool
*/
public static function mkdir($catalogue)
{
if (! file_exists($catalogue)) {
self::mkdir(dirname($catalogue));
mkdir($catalogue, 0777);
}
return true;
}

/**
* 写入日志.
* writeLog.
* @param $path
* @param $content
* @param int $flags
* @param null $context
* @return bool|int
*/
public static function writeLog($path, $content, $flags = FILE_APPEND, $context = null)
{
self::mkdir(dirname($path));
return file_put_contents($path, "\r\n" . $content, $flags, $context);
}

/**
* 遍历目录
* scanDirectory.
* @param $dirPath
* @return array
*/
public static function scanDirectory($dirPath)
{
if (! is_dir($dirPath)) {
return [];
}

$dirPath = rtrim($dirPath, '/') . '/';

$dirs = [$dirPath];

$fileContainer = [];
try {
do {
$workDir = array_pop($dirs);
$scanResult = scandir($workDir);
foreach ($scanResult as $files) {
if ($files == '.' || $files == '..') {
continue;
}
$realPath = $workDir . $files;
if (is_dir($realPath)) {
array_push($dirs, $realPath . '/');
} elseif (is_file($realPath)) {
$fileContainer[] = $realPath;
}
}
} while ($dirs);
} catch (\Throwable $throwable) {
return [];
}

return $fileContainer;
}

/**
* 获取文件夹大小
* getDirSize.
* @param $dir
* @return false|int
*/
public static function getDirSize($dir)
{
$handle = opendir($dir);
$sizeResult = 0;
while (false !== ($FolderOrFile = readdir($handle))) {
if ($FolderOrFile != '.' && $FolderOrFile != '..') {
if (is_dir("{$dir}/{$FolderOrFile}")) {
$sizeResult += self::getDirSize("{$dir}/{$FolderOrFile}");
} else {
$sizeResult += filesize("{$dir}/{$FolderOrFile}");
}
}
}

closedir($handle);
return $sizeResult;
}

/**
* 基于数组创建目录
* createDirOrFiles.
* @param $files
*/
public static function createDirOrFiles($files)
{
foreach ($files as $key => $value) {
if (substr($value, -1) == '/') {
mkdir($value);
} else {
file_put_contents($value, '');
}
}
}

/**
* removeDirectory.
* @param $dir
* @param array $options
*/
public static function removeDirectory($dir, $options = [])
{
if (! is_dir($dir)) {
return;
}
if (! empty($options['traverseSymlinks']) || ! is_link($dir)) {
if (! ($handle = opendir($dir))) {
return;
}
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($path)) {
static::removeDirectory($path, $options);
} else {
static::unlink($path);
}
}
closedir($handle);
}
if (is_link($dir)) {
static::unlink($dir);
} else {
rmdir($dir);
}
}

/**
* unlink.
* @param $path
* @return bool
*/
public static function unlink($path)
{
$isWindows = DIRECTORY_SEPARATOR === '\\';

if (! $isWindows) {
return unlink($path);
}

if (is_link($path) && is_dir($path)) {
return rmdir($path);
}

try {
return unlink($path);
} catch (\Exception $e) {
return false;
}
}

/**
* getMimeType.
* @param $file
* @return null|mixed
*/
public static function getMimeType($file)
{
if (extension_loaded('fileinfo')) {
$info = finfo_open(FILEINFO_MIME_TYPE);
if ($info) {
$result = finfo_file($info, $file);
finfo_close($info);

if ($result !== false) {
return $result;
}
}
}
return null;
}
}
Loading