Write the Code. Change the World.

12月 02

web 页面自适应处理。 其实,要说的是移动端网页自适应。只要设计图宽度标准化(有固定宽度,一般是 750px 宽度为标准),就方便实现整个页面的自适应。

阅读全文 >>

11月 25

Laravel Octane 通过使用功能强大的应用程序服务器(包括 SwooleRoadRunner )为应用程序提供服务,从而增强了应用程序的性能。Octane引导您的应用程序一次,将其保存在内存中,然后以超音速提供请求。

热点

安装条件

  • PHP8+
  • laravel v.8.37+

安装

可以通过Composer软件包管理器安装Octane:

composer require laravel/octane

安装Octane之后,您可以执行 octane:install Artisan 命令,该命令会将Octane的配置文件安装到您的应用程序中:

php artisan octane:install

RoadRunner

RoadRunner 由使用 Go 构建的 RoadRunner 二进制文件提供动力。首次启动基于 RoadRunner 的 Octane 服务器时,Octane 将为您下载并安装 RoadRunner 二进制文件。

RoadRunner Via Laravel Sail

RoadRunner 具体使用可以查看原文。

启动你的服务

可以通过 octane:startArtisan 命令启动 Octane 服务器。默认情况下,此命令将利用 server 应用程序 octane 配置文件的配置选项指定的服务器:

php artisan octane:start
# 设置应用HTTPS.配置
OCTANE_HTTPS=false

# 设置启动服务的容器
OCTANE_SERVER=swoole

# 应用代码热加载
php artisan octane:start --watch

注意 使用该命令之前,应该确保本地安装了Node 服务.您应该在您的project:library中安装Chokidar 文件监视库:

npm install --save-dev chokidar

您可以使用 watch 应用程序的 config/octane.php 配置文件中的配置选项来配置应监视的目录和文件。

指定worker进程数

默认情况下,Octane 将为您的计算机提供的每个 CPU 内核启动一个应用程序请求工作程序。然后,这些工作程序将在进入您的应用程序时用于处理传入的HTTP请求。您可以–workers在调用 octane:star t命令时手动指定要使用该选项的工人数量:

php artisan octane:start --workers=4

如果使用的是 Swoole 应用程序服务器,则还可以指定要启动的“任务工作者”数量:

php artisan octane:start --workers=4 --task-workers=6

指定最大的请求数

php artisan octane:start --max-requests=250

服务重启

您可以使用以下 octane:reload 命令正常重启 Octane 服务器的应用程序工作程序。通常,应在部署后执行此操作,以便将新部署的代码加载到内存中并用于处理后续请求:

php artisan octane:reload

服务停止

您可以使用 octane:stopArtisan 命令停止 Octane 服务器:

php artisan octane:stop

查看服务状态

php artisan octane:status

Octane 依赖注入

由于 Octane 会一次引导您的应用程序并在处理请求时将其保存在内存中,因此在构建应用程序时应注意一些注意事项。例如,您的应用程序服务提供商的registerand boot 方法仅在请求启动程序最初启动时执行一次。在后续请求中,相同的应用程序实例将被重用。
有鉴于此,在将应用程序服务容器或请求注入到任何对象的构造函数中时,应格外小心。这样,该对象可能具有旧版本的容器或后续请求中的请求。
Octane 将自动处理重置请求之间的任何第一方框架状态。但是,Octane 并不总是知道如何重置应用程序创建的全局状态。因此,您应该了解如何以Octane 友好的方式构建应用程序。下面,我们将讨论使用辛烷值时可能引起问题的最常见情况。

容器注入

通常,应避免将应用程序服务容器或 HTTP 请求实例注入其他对象的构造函数中。例如,以下绑定将整个应用程序服务容器注入到作为单例绑定的对象中:

use App\Service;

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(Service::class, function ($app) {
        return new Service($app);
    });
}

在此示例中,如果 Service 在应用程序启动过程中解析了该实例,则该容器将被注入到服务中,并且该 Service 实例将在后续请求中保留该容器。对于您的特定应用程序,这可能不是问题;但是,这可能导致容器意外丢失在引导周期后期或后续请求中添加的绑定。

解决方法是,您可以停止将绑定注册为单例,也可以将容器解析器闭包注入始终解析当前容器实例的服务中:

use App\Service;
use Illuminate\Container\Container;

$this->app->bind(Service::class, function ($app) {
    return new Service($app);
});

$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance());
});

全局 app 帮助器和 Container::getInstance() 方法将始终返回应用程序容器的最新版本。

请求注入

通常,应避免将应用程序服务容器或HTTP请求实例注入其他对象的构造函数中。例如,以下绑定将整个请求实例注入到作为单例绑定的对象中:

use App\Service;

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(Service::class, function ($app) {
        return new Service($app['request']);
    });
}

在此示例中,如果Service在应用程序启动过程中解析了实例,则HTTP请求将被注入到服务中,并且该Service实例将在后续请求中保留相同的请求。因此,所有标头,输入和查询字符串数据以及所有其他请求数据都将不正确。

解决方法是,您可以停止将绑定注册为单例,或者可以将请求解析程序闭包注入始终解析当前请求实例的服务中。或者,最推荐的方法只是在运行时将对象需要的特定请求信息传递给对象的方法之一:

use App\Service;

$this->app->bind(Service::class, function ($app) {
    return new Service($app['request']);
});

$this->app->singleton(Service::class, function ($app) {
    return new Service(fn () => $app['request']);
});

// Or...

$service->method($request->input('name'));

全局 request 帮助程序将始终返回应用程序当前正在处理的请求,因此可以在您的应用程序中安全使用。

配置文件注入

通常,应避免将配置实例注入其他对象的构造函数中。例如,以下绑定将配置注入到作为单例绑定的对象中:

use App\Service;

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->singleton(Service::class, function ($app) {
        return new Service($app->make('config'));
    });
}

在此示例中,如果配置值在两次请求之间更改,则该服务将无法访问新值,因为它取决于原始存储库实例。
解决方法是,您可以停止将绑定注册为单例,或者可以将配置存储库解析器闭包注入到该类中:

use App\Service;
use Illuminate\Container\Container;

$this->app->bind(Service::class, function ($app) {
    return new Service($app->make('config'));
});

$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance()->make('config'));
});

全局 config 将始终返回配置的最新版本,因此可以在您的应用程序中安全使用。

管理内存泄漏

请记住,Octane 在两次请求之间将您的应用程序保留在内存中;因此,将数据添加到静态维护的阵列将导致内存泄漏。例如,由于对应用程>序的每个请求将继续向静态$data数组添加数据,因此以下控制器发生内存泄漏:

use App\Service;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return void
 */
public function index(Request $request)
{
    Service::$data[] = Str::random(10);

    // ...
}

并发任务

提示该功能需要使用 Swoole

使用 Swoole 时,您可以通过轻量级后台任务同时执行操作。您可以使用 Octane:: tick concurrently 方法完成此操作。您可以将此方法与PHP数组解>构相结合,以检索每个操作的结果:

use App\User;
use App\Server;
use Laravel\Octane\Facades\Octane;

[$users, $servers] = Octane::concurrently([
    fn () => User::all(),
    fn () => Server::all(),
]);

由 Octane 处理的并发任务利用 Swoole 的 “task workers”,并在与传入请求完全不同的过程中执行。可用于处理并发任务的工作者数量由 –task-workers命令上的 octane:start 指令确定:

php artisan octane:start --workers=4 --task-workers=6

定时器 & 时间间隔

  • 提示该功能需要使用Swoole

使用 Swoole 时,您可以注册将在每指定的秒数内执行的 “tick” 操作。您可以通过 tick 方法注册 “ tick” 回调。提供给该tick方法的第一个参数应该是代表股票行情指示器名称的字符串。第二个参数应该是可调用的,它将在指定的时间间隔被调用。
在此示例中,我们将注册一个闭包,每10秒调用一次。通常,tick应在boot应用程序的服务提供者之一的方法内调用该方法:

Octane::tick('simple-ticker', fn () => ray('Ticking...'))
       ->seconds(10);

使用该 immediate 方法,您可以指示 Octane 在 Octane 服务器最初启动时立即调用 tick 回调,此后每隔 N 秒:

Octane::tick('simple-ticker', fn () => ray('Ticking...'))
        ->seconds(10)
        ->immediate();

Octane 缓存

  • 这功能依赖于Swoole

使用 Swoole 时,您可以利用 Octane 缓存驱动程序,该驱动程序提供每秒高达 200 万次操作的读写速度。因此,对于需要从其缓存层实现极高读/写速度的应用程序而言,此缓存驱动程序是一个绝佳选择。
该缓存驱动程序由 Swoole 表提供动力。缓存中存储的所有数据对服务器上的所有工作人员均可用。但是,重新启动服务器后,将刷新缓存的数据:

Cache::store('octane')->put('framework', 'Laravel', 30);

缓存间隔

除了 Laravel 缓存系统提供的典型方法外,Octane 缓存驱动程序还具有基于间隔的缓存。这些缓存将按指定的时间间隔自动刷新,并应使用 boot 您的应用程序的服务提供商之一的方法进行注册。例如,以下缓存将每五秒钟刷新一次:

use Illuminate\Support\Str;

Cache::store('octane')->interval('random', function () {
    return Str::random(10);
}, seconds: 5);

进程间共享内存 (table)

高性能共享内存

使用 Swoole 时,您可以定义自己的任意 Swoole 表并与之交互。Swoole 表提供了极高的性能吞吐量,并且服务器上的所有工作人员都可以访问这些表中的数据。但是,重新启动服务器后,其中的数据将丢失。

表应在tables应用程序的octane配置文件的配置数组中定义。已经为您配置了一个示例表,该表最多允许1000行。可以通过在列类型之后指定列大小来配置字符串列的最大大小,如下所示:

'tables' => [
    'example:1000' => [
        'name' => 'string:1000',
        'votes' => 'int',
    ],
],

要访问表,可以使用以下 Octane::table 方法:

use Laravel\Octane\Facades\Octane;

Octane::table('example')->set('uuid', [
    'name' => 'Nuno Maduro',
    'votes' => 1000,
]);

return Octane::table('example')->get('uuid');

通过Swoole table 支持的列类型:string,int,和 float。

参考

文章来源
译文
laravel 9 发布
JWT
还要为性能选择 Lumen 吗
Laravel 清单

阅读全文 >>

11月 10

运营商如果不是一成不变。那么就要面对更换所要面临的问题。先换 oss 到 cos

换吧

迁移工具: https://cloud.tencent.com/document/product/436/15392

liunx 下,下载好工具,配置好 config。安装必须的环境(JAVA),执行 sh start_migrate.sh 开始迁移。等到结束就 ok。

换到 cos,laravel 的工具包也跟着换了 https://github.com/overtrue/laravel-filesystem-cos

阅读全文 >>

11月 09

从零开始,来吧

php 下载地址集:https://www.php.net/downloads

先下载解压 php 包

# 先把文件下到这个目录下来
cd /usr/local/src/php

wget https://www.php.net/distributions/php-7.4.25.tar.gz 

# 提示说 错误: “www.php.net” 的证书不可信 错误: “www.php.net” 的证书使用不安全的算法签名。
# wget 搞不定,我们用 curl 来弄
curl -o php-7.4.25.tar.gz https://www.php.net/distributions/php-7.4.25.tar.gz

# 再解压
tar -xzvf php-7.4.25.tar.gz

安装依赖包

能用 yum 装的就用 yum 装,不行的再源码编译安装

yum -y install gcc gcc-c++

yum -y install sqlite-devel

yum install libxslt-devel

yum install cmake

# 还是要手动安装 oniguruma
请参考:[https://blog.vini123.com/379](https://blog.vini123.com/379)

yum -y install libxml2-devel openssl-devel curl-devel libjpeg-devel libpng-devel libicu-devel freetype-devel openldap-devel openldap openldap-devel

安装 gd库,freetype2,libzip ,请参考:https://blog.vini123.com/378

安装

如果之前没建立其用户组,先建立一个用户组

groupadd nginx
useradd -g nginx -M nginx

参考

https://www.cnblogs.com/alliancehacker/p/12255445.html

https://blog.vini123.com/378

https://blog.vini123.com/303

阅读全文 >>

10月 11

《鱿鱼游戏》中的6个游戏,试探出来太多人性的弱点,但那是在生与死的边界进行抉择,加上巨大的利益诱惑,这种时刻展现的人性必然是经不起试探的,所以观众也不会当真。因为我们相信自己不会遭遇 《鱿鱼游戏》中同样的处境。但问题是:这样的游戏换成你来玩,你会比男主更善良吗?

在线

https://www.ai66.cc/dianshiju/rihanju/16711.html

迅雷下载:magnet:?xt=urn:btih:39487F99E58852F4BDDB404998EC266726D6ACBC

解说

网飞够狠。

冷不丁放出一个大招。

一部大制作+大尺度+韩剧顶配阵容的九集爽剧,一口气放出。

第一集就让人上了头,连夜刷完。

太爽了太爽了,真是好久没看到这么爽的韩剧了——《鱿鱼游戏》。

9月17日在网飞独家上线,不仅一口气杀上豆瓣热度第一,更拿下网飞世界榜排名第4,美国区排名第1。

甚至,还一口气拯救了上半年略显低迷的韩剧,在口碑炸裂但热度相对一般的《机智的医生生活2》、继续口碑炸裂但过于残酷难下饭的《D.P:逃兵追缉令》,以及雷声大雨点小的《北方的阿信》之后,终于出现了一部豆瓣评分稳在8.0,同时还热度爆棚的韩剧。

凭什么这么炸?

一是题材,二是阵容。

题材,一场神秘竞赛,456名参赛选手为456亿韩元展开激烈争夺,赢家只能是——最后活着的那个人,或者那几个人。

阅读全文 >>

8月 29

默认主机名乱七八糟,不好看也找不到意义。修改主机名就很有必要。怎么做呢。

操作一波

# 将 preserve_hostname 值改为 true ,保存并退出
vim /etc/cloud/cloud.cfg

# 设置主机名,这里我设置为 xiangrong (云想衣裳花想容,春风拂槛露华浓)
hostnamectl set-hostname xiangrong

退出连接,重新登录就发现修改好了。

阅读全文 >>

8月 28

如上图,在调试的时候,你会看到 user agent stylesheet 定义的样式,而且是不能改的。

user agent stylesheet是浏览器自动加上的格式,user agent stylesheet将被你在自己的css中设置的任何内容覆盖。它们只是最底层:在没有页面或用户提供的任何css的情况下,浏览器仍然必须以某种方式呈现内容,而css只是描述了这一点。

因此,如果你认为css存在问题,那么你的HTML或css或两者(您没有写任何内容)确实存在问题。

解决方法

  • 方法一

由于 user agent stylesheet 的优先级很低,自己写样式覆盖即可。在你的css中添加被user agent stylesheet所覆盖了的样式,例如,我这可以重新定义div的样式:

div{
    display: inline-block;
}

阅读全文 >>

8月 26

oss 上传 api 中,一个是上传 file ,有个是上传 content 。如何处理各种文件以及数据格式呢。常见的一种操作是上传图片。这里就弄弄看。

操作一波

如果上传的图片是 base64 ,先要转换。我们这里定义一个函数。

function base64ToImage($file)
{
    if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $file, $result)) {
        $image = base64_decode(str_replace($result[1], '', $file));
        return $image;
    }
    return null;
}

我们还知道怎么拼接完成的 url。

# 这样就可以获取公网 url,当然你也可以获取内网 url
$url = App\Services\Oss::getPublicObjectURL($ossKey);

在这里,我们是先将文件传到服务器,再从服务器将文件传到 oss 上。这时,就用内网上传即可。流量要钱的,这样蛮好的。为什么不直接传 oss 上呢。直接传服务端逻辑不方便操作,直接传权限控制不好处理。反正就这种操作吧。

上边的还没说完,转换后,需要内网上传。

$file = base64ToImage($request->file);
$ossKey = ''upload/images/meets/1.jpg;
if($file) {
    $uploaded  = Oss::privateUploadContent($ossKey, $file);
}

想要删也可以的

Oss::privateDeleteObject($ossKey);

图片处理

https://help.aliyun.com/document_detail/47735.html

https://help.aliyun.com/product/31815.html

阅读全文 >>