Alex

有的故事值得一直说下去.
Home » Latest Posts

介绍: https://blog.thetbw.xyz/archives/share-about-mis-dev-tunnels

长话短说
地址: https://learn.microsoft.com/zh-cn/azure/developer/dev-tunnels/get-started

安装使用

winget install Microsoft.devtunnel
devtunnel user login
devtunnel host -p 8080
限制:

名称 限制
带宽 5 GB 每用户
隧道数 10 每用户
活动连接 20 每端口
端口数 10 每个隧道
http 请求速率 1500/min 每端口
速率 最高 20 MB/s 每隧道
最大 http 请求体大小 16 MB

这适用于我最新版本的Laravel 5.7。注意我是如何包含__env变量的,这样@include、@foreach等函数就可以工作了。

public static function renderBlade($string, $data = null)
{

if (!$data) {
$data = [];
}
$data['__env'] = app(\Illuminate\View\Factory::class);
$php = Blade::compileString($string);
$obLevel = ob_get_level();
ob_start();
extract($data, EXTR_SKIP);
try {
eval('?' . '>' . $php);
} catch (Exception $e) {
while (ob_get_level() > $obLevel) {
ob_end_clean();
}
throw $e;
} catch (Throwable $e) {
while (ob_get_level() > $obLevel) {
ob_end_clean();
}
throw new FatalThrowableError($e);
}
return ob_get_clean();

}
原来我没有将参数数组传递给解析Blade结构的方法。我的假设是Mail::send方法负责使变量可用,它将变量作为第二个参数。我也不得不使用extract($args, EXTR_SKIP)。

$generated = Blade::compileString($string);

ob_start(); extract($args, EXTR_SKIP)

try
{

eval($generated);

}
catch (\Exception $e)
{

ob_get_clean(); throw $e;

}

$content = ob_get_clean();

return $content;

异步调用的概念
异步调用是指在发起请求后不等待响应,而是立即返回,在后续处理中获取响应的方式。相对于同步调用,它能够提高程序的并发能力和响应速度。

在PHP中,实现异步调用有多种方法,下面将详细介绍这四种方法。

方法一:使用cURL的异步选项
cURL(Client URL Library)是一个很常用的、强大的网络请求库。在PHP中,cURL也是默认提供的扩展库之一。cURL提供了一系列选项,让我们可以在请求时设置异步选项。

下面是一个示例代码:

function request($url, $callback) {

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOSIGNAL, true); // 开启异步选项
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); // 设置超时时间
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);
curl_setopt($ch, CURLOPT_FORBID_REUSE, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_exec($ch);
curl_close($ch);

}

function callback($ch, $content) {

echo 'result: ' . $content . PHP_EOL;

}

$url = 'https://www.example.com';
request($url, 'callback');
这个代码中,我们使用了curl_setopt函数设置了异步选项,并设置了超时时间。在请求启动后,程序不会等待响应,而是立即返回并输出result。请求的响应内容将在回调函数中输出。

方法二:使用pcntl_fork实现进程异步
在PHP中,可以使用pcntl_fork函数来创建子进程,达到异步调用的效果。子进程可以独立和父进程进行操作,这就使得程序的执行速度得到了提升。

下面是一个示例代码:

function async_request($url, $callback) {

$pid = pcntl_fork();
if ($pid === -1) {
die('fork failed');
} else if ($pid === 0) {
$content = file_get_contents($url);
call_user_func($callback, $content);
exit(0);
}

}

function callback($content) {

echo 'result: ' . $content . PHP_EOL;

}

$url = 'https://www.example.com';
async_request($url, 'callback');
这个代码中,我们使用pcntl_fork函数创建了一个子进程,子进程中请求了$url并将返回的内容传递给回调函数。在父进程中,程序不会等待子进程的完成,而是立即返回。

方法三:使用swoole扩展
Swoole是一个基于PHP的C++扩展库,提供了一些函数和类,使PHP具备类似Node.js、Go等语言的协程、异步IO等高性能特性。使用Swoole扩展可以实现高并发、低消耗的异步调用。

下面是一个示例代码:

$client = new swoole_http_client('www.example.com', 80);
$client->set([

'keep_alive' => false,
'timeout' => 10,

]);
$client->setHeaders([

'Host' => 'www.example.com',
"User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299",
"Accept-Encoding" => "gzip, deflate",

]);
$client->on('close', function(swoole_http_client $cli) {

echo "conn closed\n";

});
$client->get('/', function(swoole_http_client $cli) {

echo 'result: ' . $cli->body . PHP_EOL;
$cli->close();

});
这个代码中,我们使用了Swoole的swoole_http_client类来实现异步调用。在设置连接选项和请求头后,我们使用了get方法发起异步请求。在请求得到响应后,回调函数中输出响应内容。

方法四:使用ReactPHP
ReactPHP是一个标准的PHP库,用于实现高性能、非阻塞式、可扩展的异步应用。通过使用ReactPHP,我们可以很方便地实现异步HTTP请求、异步TCP/UDP请求等。

下面是一个示例代码:

$loop = React\EventLoop\Factory::create();

$dnsResolverFactory = new React\Dns\Resolver\Factory();
$dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop);

$factory = new React\HttpClient\Factory();
$client = $factory->create($loop, $dnsResolver);

$request = $client->request('GET', 'http://www.example.com/');
$request->on('response', function (React\HttpClient\Response $response) {

$response->on('data', function ($data) {
echo 'result: ' . $data . PHP_EOL;
});

});

$request->end();

$loop->run();
这个代码中,我们首先使用了React\EventLoop来创建事件循环。然后,我们使用React\HttpClient的工厂类来创建一个异步HTTP请求对象。在异步请求中,我们使用回调函数输出响应内容。最后,我们启动事件循环。

问题
使用Django开发web项目,在执行数据迁移时遇到以下错误

django.db.utils.OperationalError: table "xxx" already exists

django.db.utils.ProgrammingError: relation "xxx" already exists
原因是相关数据表已经存在了

解决方法
在执行迁移时加上--fake-initial参数

python manage.py migrate --fake-initial
如果外键存在,需要初始化多张表,且部分数据表已经创建,部分未创建,则可以使用--fake 参数来处理,为对应app的名字

python manage.py migrate --fake
详细步骤请参考官方文档

注:如果执行完以上命令依然报错,请确认app下migrations目录的文件与django_migrations表中的记录是否一致,不一致则需要删除对应的迁移文件和django_migrations表中对应的记录数据

拓展
Django在执行migrate迁移时会依次执行以下四件事情:

判定迁移:对项目中改动过且未迁移的文件进行迁移(Django通过对比app的migrations目录下的文件和django_migrations表中的数据来判定是否有新的迁移变动)

新增迁移映射关系:在django_content_type表中新增映射关系(app与model关系)

新增迁移权限:在auth_permission表中新增权限

执行迁移:生成新的数据表或对已有数据表进行改动

其中,

migrate --fake只执行了第一步,并生成迁移记录

migrate --fake-initial执行了前三步,不实际变动数据库

而migrate则依次执行所有步骤

https://search.censys.io/search?resource=hosts&sort=RELEVANCE&per_page=25&virtual_hosts=EXCLUDE&q=account.jetbrains.com%2Ffls-auth

Life is fantastic
🥕 More