首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
184 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
33
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-08-12
使用workerman加速任意项目
使用workerman加速任意项目众所周知,workerman是基于php cli的,由于php cli模式下无法使用php自带的header、sesion、cookie等函数,这导致将传统的php项目无法直接在workerman容器下直接运行。我一度以为让传统业务在workerman中运行,就必须更改框架甚至业务代码以适配workerman,直到joanhey发了一个issue,打破了我的认知。他们发布了一个名叫AdapterMan的项目,它可以做到不更改传统框架代码的情况下让你的传统php项目放到workerman中正常运行,并且他们公司已经在生产环境用了2年。注意,是零代码改动直接让laravel、lumen、Slim等框架的项目在workerman上运行。目前他们已经在laravel、lumen、Slim、Symfony、CakePHP、Yii2、KumbiaPHP 等做了初步压力测试,性能有很大的提升。以下是压测结果Laravel 8Fw Plaintext Json Single query Multiple query Updates FortunesLaravel 14,799 14,770 9,263 3,247 1,452 8,354Laravel Roadrunner 482 478 474 375 359 472Laravel Swoole 38,824 37,439 21,687 3,958 1,588 16,035Laravel Laravel s 54,617 49,372 23,677 2,917 1,255 16,696Laravel Workerman 103,004 99,891 46,001 5,828 1,666 27,158Laravel with Workerman % gain 596.02% 576.31% 396.61% 79.489% 14.738% 225.09%截图Symfony 6截图Fw Plaintext Json Single query Multiple query Updates FortunesSymfony 38,231 37,557 12,578 10,741 3,420 10,741Symfony Workerman 210,796 197,059 107,050 13,401 4,062 71,092Lumen 9Fw Plaintext Json Single query Multiple query Updates FortunesLumen 18,998 18,616 10,791 3,496 1,461 9,223Lumen Swoole 44,861 43,598 24,255 4,178 1,599 16,854Lumen Laravel s 93,335 82,745 31,567 3,030 1,282 21,130Lumen Workerman 185,126 177,667 58,729 5,857 1,662 31,430Slim with WorkermanWithout ORMFramework JSON 1-query 20-query Fortunes Updates PlaintextSlim 4 38,305 34,272 12,579 32,634 2,097 35,251Slim 4 Workerman 129,393 81,889 15,803 73,212 2,456 134,531Slim 4 Workerman pgsql * 102,926 19,637 92,752 14,875Lumen v9截图接入代码类似<?php require_once __DIR__ . '/vendor/autoload.php'; use AdaptermanAdapterman; use WorkermanWorker; Adapterman::init(); $http_worker = new Worker('http://0.0.0.0:8080'); $http_worker->count = 8; $http_worker->name = 'AdapterMan'; $http_worker->onWorkerStart = static function () { //init(); require __DIR__.'/start.php'; }; $http_worker->onMessage = static function ($connection, $request) { $connection->send(run()); }; Worker::runAll();项目地址:https://github.com/joanhey/AdapterMan 强烈建议大家为其点赞(点星星)相关链接:https://github.com/walkor/workerman/issues/824
2023年08月12日
30 阅读
0 评论
0 点赞
2023-08-12
多年来 PHP 对象的演变
多年来 PHP 对象的演变这有趣的小帖子可视化数据传输对象这些年来是如何演变的。2014 年 8 月:PHP 5.6让我们从 PHP 5.6 开始,这是大多数没有现代 PHP 知识的人可能认为 PHP 代码仍然看起来的样子。我只会给你代码,我会提到未来版本的变化。class BlogData{/** @var string */ private $title; /** @var State */ private $state; /** @var \DateTimeImmutable|null */ private $publishedAt; /*** @param string $title * @param State $state * @param \DateTimeImmutable|null $publishedAt */ public function __construct( $title, $state, $publishedAt = null ) { $this->title = $title; $this->state = $state; $this->publishedAt = $publishedAt; } /** * @return string */ public function getTitle() { return $this->title; } /** * @return State */ public function getState() { return $this->state; } /** * @return \DateTimeImmutable|null */ public function getPublishedAt() { return $this->publishedAt; }}2015 年 12 月:PHP 7.0PHP 7.0 引入了一些主要的新语法特性:标量类型和返回类型是这里最值得注意的。Nullable 类型还不是一个东西,所以我们仍然需要为我们的 nullable 使用 doc 块类型$publishedAt:class BlogData{/** @var string */ private $title; /** @var State */ private $state; /** @var \DateTimeImmutable|null */ private $publishedAt; /*** @param \DateTimeImmutable|null $publishedAt */ public function __construct( string $title, State $state, $publishedAt = null ) { $this->title = $title; $this->state = $state; $this->publishedAt = $publishedAt; } public function getTitle(): string { return $this->title; } public function getState(): State { return $this->state; } /** * @return \DateTimeImmutable|null */ public function getPublishedAt() { return $this->publishedAt; }}2016 年 12 月:PHP 7.1PHP 7.1 终于出现了可以为空的类型,所以我们可以删除更多的文档块:class BlogData{/** @var string */ private $title; /** @var State */ private $state; /** @var \DateTimeImmutable|null */ private $publishedAt; public function __construct( string $title, State $state, ?DateTimeImmutable $publishedAt = null ) { $this->title = $title; $this->state = $state; $this->publishedAt = $publishedAt; } public function getTitle(): string { return $this->title; } public function getState(): State { return $this->state; } public function getPublishedAt(): ?DateTimeImmutable { return $this->publishedAt; }}2017 年 11 月:PHP 7.2虽然 7.2 中有一些令人兴奋的功能,例如参数类型扩展和object类型,但我们无法在此版本中清理特定的 DTO。2018 年 12 月:PHP 7.3PHP 7.3也是如此,这里没什么可看的。2019 年 11 月:PHP 7.4PHP 7.4是一个不同的故事!现在有了类型化的属性——终于!class BlogData{private string $title; private State $state; private ?DateTimeImmutable $publishedAt; public function __construct( string $title, State $state, ?DateTimeImmutable $publishedAt = null ) { $this->title = $title; $this->state = $state; $this->publishedAt = $publishedAt; } public function getTitle(): string { return $this->title; } public function getState(): State { return $this->state; } public function getPublishedAt(): ?DateTimeImmutable { return $this->publishedAt; }}我如何在不到 5 分钟的时间内将 PhpStorm 设置为干净且最小化。干净简约的 PhpStorm干净简约的 PhpStorm2020 年 11 月:PHP 8.0另一个游戏规则改变者:PHP 8增加了提升属性;此外,参数列表中的尾随逗号现在是一回事!class BlogData{public function __construct( private string $title, private State $state, private ?DateTimeImmutable $publishedAt = null, ) {} public function getTitle(): string { return $this->title; } public function getState(): State { return $this->state; } public function getPublishedAt(): ?DateTimeImmutable { return $this->publishedAt; }}2021 年 11 月:PHP 8.1接下来,我们到达PHP 8.1。只读属性是一个东西,它允许我们像这样编写我们的 DTO:class BlogData{public function __construct( public readonly string $title, public readonly State $state, public readonly ?DateTimeImmutable $publishedAt = null, ) {}}2022 年 11 月:PHP 8.2最后,我们到达了PHP 8.2——尚未发布。每当一个类只有只读属性时,可以将类本身标记为只读,而不是每个单独的属性:readonly class BlogData{public function __construct( public string $title, public State $state, public ?DateTimeImmutable $publishedAt = null, ) {}}那是完全不同的,你不觉得吗?看看这门语言在近十年的时间里是如何演变的很有趣。如果您在 10 年前提出 8.2 语法,您可能会被称为疯子。今天也是如此,我相信我们会在十年后回顾这一点,并想知道“我们是怎么忍受的?”。
2023年08月12日
7 阅读
0 评论
0 点赞
2023-08-12
使用PHP做 http pxory 缓存&代理, 使用redis做缓存,支持毫秒过期,拥有超高性能
使用PHP做 http pxory 缓存&代理, 使用redis做缓存,支持毫秒过期,拥有超高性能<?php //PHP http pxory 缓存&代理, 使用redis做缓存,支持毫秒过期,拥有超高性能 $url=@$_GET['url']; if (empty($_GET['url'])) { echo 'url is empty '; exit; } $path=parse_url($url, PHP_URL_PATH); $key=$path; $redis = new Redis(); $redis->pconnect('127.0.0.1', 6379); if ($content=$redis->get($key)) { echo $content; exit; } // Client $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //注意,毫秒超时一定要设置这个 curl_setopt($ch, CURLOPT_TIMEOUT_MS, 500); //超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用 $data = curl_exec($ch); $curl_errno = curl_errno($ch); $curl_error = curl_error($ch); curl_close($ch); if ($curl_errno > 0) { echo "cURL Error ($curl_errno): $curl_error\n"; } else { // $redis->setEx('key', 3600, 'value');//以秒为单位 $redis->pSetEx($key, 50000, $data); // 将参数中的字符串值设置为键的值,并带有生存时间 pSetEx以毫秒为单位. echo $data; exit; }使用方法:http://localhost/proxy.php?url=https://www.xxxxxxx.com:3004/rooms/5f392ac745f6cd207b5301db经压力测试,性能超高.!!
2023年08月12日
12 阅读
0 评论
0 点赞
2023-08-12
异步 PHP — 多进程、多线程和协程
异步 PHP — 多进程、多线程和协程让我们看一下这段典型的 PHP 代码:function names(){$data = Http::get('data.location/products')->json(); $names = []; foreach ($data as $item){ $names[] = $item['name']; } return $names;}我们发送一个返回项目数组的 HTTP 请求,然后我们将每个项目的名称存储在一个$names数组中。执行此函数所花费的时间等于请求的持续时间加上构建数组所花费的时间。如果我们想为不同的数据源多次运行这个函数怎么办:$products = names('/products');$users = names('/users');运行此代码所花费的时间等于两个函数组合的持续时间:HTTP request to collect products: 1.5 secondsBuilding products names array: 0.01 secondsHTTP request to collect users: 3.0 secondsBuilding users names array: 0.01 secondsTotal: 4.52 seconds图片这称为同步代码执行,或一次执行一件事。为了使此代码运行得更快,您可能希望异步执行它。那么,如果我们想实现这一目标,我们有哪些选择呢?在不同的进程中执行。在不同的线程中执行。在协程/纤维/绿色线程中执行。在不同的进程中执行在单独的进程中运行这些函数调用中的每一个,都会为操作系统提供并行运行它们的任务。如果您有一个多核处理器,我们现在都有,并且周围有 2 个空闲内核,操作系统将使用两个内核并行(同时)执行进程。但是,在大多数情况下,机器上运行的其他进程需要使用可用的内核。在这种情况下,操作系统将在这些进程之间共享 CPU 时间。换句话说,可用内核将在处理我们的两个进程和其他进程之间切换。在这种情况下,我们的进程将同时执行。这两个进程的执行时间大约是 3.03 秒(我知道不是 100% 准确)。这个结论是基于这样一个事实:最慢的请求需要 3 秒,2 次网络调用需要 10 毫秒,两个用于收集名称的循环各需要 10 毫秒。核心内部的执行将如下所示:Switch to process 1Start HTTP request to collect productsSwitch to process 2Start HTTP request to collect usersSwitch to process 1If a response came, then build products names arraySwitch to process 2If a response came, then build users names array因此,当 CPU 等待第一个请求的响应时,它会发送第二个请求。然后等到任何请求返回,然后再继续该过程。多处理是在 PHP 中实现异步代码执行的一种简单方法。但是,它并不是性能最高的。因为创建进程相对昂贵,并且每个进程都需要在内存中拥有自己的私有空间。进程之间的切换(上下文切换)也有开销。您可以使用 Laravel 队列并启动固定数量的工作人员(进程)并让它们保持活动状态以处理您的任务。这样你就不必每次想要异步运行时都创建新进程。但是,上下文切换和内存分配的开销仍将适用。同样对于工作人员,您需要管理如何从工作人员内部的代码执行中接收结果。多处理和 Laravel 工作人员已经为数百万个应用程序做得很好。因此,当我说它不是相对于其他选项时性能最好的。不要只是阅读本文并认为多处理和队列不好。好?在不同的线程中执行一个进程在内存中有自己的私有空间,一个进程可能有多个线程。所有线程都与进程位于相同的内存空间中。这使得生成线程比生成进程更便宜。但是,上下文切换仍然会发生。当你有太多线程时,比如有太多进程,你机器上的一切都会变慢。因为 CPU 内核在很多上下文之间切换。此外,由于多个线程同时访问相同的内存空间,可能会发生争用情况。除此之外,不再支持PHP 中的多线程。在 coroutines/fibers/green-threads 中执行这个“东西”有很多名字。但是我们称它为“协程”,因为它是最常用的术语。协程就像一个线程,它共享它在内部创建的进程的内存,但它不是一个实际的线程,因为操作系统对此一无所知。操作系统级别的协程之间没有上下文切换。运行时控制切换发生的时间,这比 OS 上下文切换成本更低。让我们将代码转换为使用协程。此代码仅用于演示,如果您运行它将不起作用:$products = [];$users = [];go(fn() => $products = names('/products'));go(fn() => $users = names('/users'));协程背后的想法是运行时将安排同时运行这些回调。在每个协程内部,代码可以显式地将控制权交给运行时,以便它可以运行另一个协程。在任何给定时间,只有一个协程正在执行。所以如果我们分解我们的代码,它会是这样的:go(function(){$data = Http::get('data.location/products')->json(); // yields foreach(...)});go(function(){$data = Http::get('data.location/users')->json(); // yields foreach(...)});运行时将执行第一个协程直到它产生,然后执行第二个协程直到它产生,然后返回到它在第一个协程中停止的位置。直到所有协程都执行完毕。然后,它将以常规同步方式继续执行代码。现在你可能有两个问题;首先,什么时候应该屈服?第二,我们如何实现它?在我们的示例中,每个协程内部都有两个操作;一个 I/O 绑定和一个 CPU 绑定。发送 HTTP 请求是一个 I\O 绑定操作,我们发送请求(输入)并等待响应(输出)。另一方面,循环是一个 CPU 密集型操作,我们正在循环一组记录并计算结果。计算是由 CPU 完成的,这就是为什么它被称为 CPU bound。如果在同一进程中运行,受 CPU 限制的工作将花费相同的时间。使工作花费更少时间的唯一方法是在不同的进程或线程中执行它。另一方面,I\O 绑定的工作可以在同一个进程内并发运行;当一个 I\O 操作正在等待输出时,另一个操作可以开始。查看我们的示例,运行时内部的执行将如下所示:Start coroutine 1Start HTTP request to collect productsCoroutine 1 yieldsSwitch to coroutine 2Start HTTP request to collect usersCoroutine 2 yieldsSwitch to coroutine 1If a response came, then build products names arraySwitch to coroutine 2If a response came, then build users names array使用协程,我们可以将 I\O 操作花费在等待上的时间用于做其他工作。通过这样做,我们同时运行所有协程。现在让我们转向我们的第二个问题:我们如何使屈服发生?我们没有。不同的框架和库必须通过在 I\O 操作等待时让出控制来支持异步执行。有一个流行的术语,你应该知道“非阻塞 I\O”。与数据库、缓存、文件系统、网络等通信的库必须适应非阻塞。如果您在协程中使用阻塞库,它将永远不会产生,因此您的协程将同步执行。主进程将等到 I\O 操作收到输出,然后再继续程序的其余部分。结论关于协程和异步执行还有很多话要说。我的计划是探索如何让 Laravel 与协程很好地配合,并在此过程中分享我的发现。在那之前,拥抱 PHP 的同步代码执行。超过 25 年,它运行良好。将您需要剪切的 I\O 绑定工作发送到队列工作程序并稍后对结果采取行动。这应该涵盖许多用例。
2023年08月12日
16 阅读
0 评论
0 点赞
2023-08-12
如何用 PHP 获取目录大小
如何用 PHP 获取目录大小function GetDirectorySize($path){ $bytestotal = 0; $path = realpath($path); if($path!==false && $path!='' && file_exists($path)){ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object){ $bytestotal += $object->getSize(); } } return $bytestotal; }
2023年08月12日
6 阅读
0 评论
0 点赞
1
...
46
47
48
...
112