PHP way to explore https:https://cdn.v2ex.com/navatar/44f6/83a8/62_normal.png?m=1644475743 https:https://cdn.v2ex.com/navatar/44f6/83a8/62_large.png?m=1644475743 2025-12-08T16:35:12Z Copyright © 2010-2018, V2EX 基于 yii2 框架开发的后台管理软件,免费 tag:www.v2ex.com,2025-12-08:/t/1177644 2025-12-08T09:17:47Z 2025-12-08T16:35:12Z sunkangchina member/sunkangchina https://github.com/yii2cms/yii2cms


MIT 协议,欢迎使用! ]]> 「一键部署你的专属服务器」——WNMP 一键包,让 Web 环境搭建回归简单 tag:www.v2ex.com,2025-12-08:/t/1177445 2025-12-08T00:41:29Z 2025-12-07T16:40:29Z mimiphp member/mimiphp 「一键部署你的专属服务器」——WNMP 一键包,让 Web 环境搭建回归简单

还在为 Nginx + PHP + 数据库 的复杂安装而头疼吗? WNMP 一键包,让这一切变成——一行命令搞定。

apt install -y curl && curl -fL https://wnmp.org/zh/wnmp.sh -o wnmp.sh && chmod +x wnmp.sh && bash wnmp.sh

一分钟安装完整 Web 环境:

系统自动优化:

安全为先 · 默认即最优:

面向开发者与站长的真正“零阻力”方案: 无论你是独立开发者、云服务商、还是边缘节点运维者,WNMP 让服务器环境部署变得和安装浏览器一样简单。 轻量、稳定、可复制 —— 一次配置,永久受益。

官方网站: https://wnmp.org 社区支持:QQ 群 1075305476 | Telegram @wnmps Github:[url]https://github.com/lowphpcom/wnmp[/url] 开源协议:GPLv3

WNMP 不仅仅是一个脚本,它是下一代 PHP 运行环境生态的起点 —— 基于 LOWPHP 的常驻内存架构,未来将带来原生级的高性能 PHP 体验。

]]>
完蛋了,为什么我感觉 PHP 的语法这么优雅呢 tag:www.v2ex.com,2025-12-05:/t/1177111 2025-12-05T05:56:07Z 2025-12-07T19:39:08Z florentino member/florentino temporal 官网示例

python:

@workflow.defn class SleepForDaysWorkflow: # Send an email every 30 days, for the year @workflow.run async def run(self) -> None: for i in range(12): # Activities have built-in support for timeouts and retries! await workflow.execute_activity( send_email, start_to_close_timeout=timedelta(secOnds=10), ) # Sleep for 30 days (yes, really)! await workflow.sleep(timedelta(days=30)) 

ruby:

 # Send an email every 30 days, for the year class SleepForDaysWorkflow < Temporalio::Workflow::Definition def execute 12.times do # Activities have built-in support for timeouts and retries! Temporalio::Workflow.execute_activity( SendEmailActivity, start_to_close_timeout: 10 ) # Sleep for 30 days (yes, really)! Temporalio::Workflow.sleep(30 * 24 * 60 * 60) end end end 

C#:

[Workflow] public class SleepForDaysWorkflow { // Send an email every 30 days, for the year [WorkflowRun] public async Task RunAsync() { for (int i = 0; i < 12; i++) { // Activities have built-in support for timeouts and retries! await Workflow.ExecuteActivityAsync( (Activities act) => act.SendEmail(), new() { StartToCloseTimeout = TimeSpan.FromSeconds(10) }); // Sleep for 30 days (yes, really)! await Workflow.DelayAsync(TimeSpan.FromDays(30)); } } } 

PHP:

class SleepForDaysWorkflow implements SleepForDaysWorkflowInterface { // Send an email every 30 days. public function sleepForDays(): void { for ($i = 0; $i < 12; $i++) { // Activities have timeouts, and will be retried by default! $this->sendEmailActivity->sendEmail(); // Sleep for 30 days (yes, really)! Workflow::sleep(30 * 24 * 60 * 60) } } } 

感觉对于 java 程序员 php 的心智负担好小啊

]]>
未来属于 PHP tag:www.v2ex.com,2025-11-20:/t/1174079 2025-11-20T15:25:25Z 2025-11-26T22:12:42Z cj323 member/cj323
这一切源于最近我家小朋友有了编程的兴趣;在尝试学第一门编程语言。让我意想不到的是,他选择了 PHP 。我很惊讶,PHP 不是没落了吗?大家讨论的都是 JS ,Go ,Rust ,Python 等等热门语言,按理说小孩网上怎么搜也不会蹦出 PHP 这三个字母吧。令我更意想不到的是,他学得津津有味。而且已经有了一些成果。观察几天后,我才发现,这一切并非偶然。

最重要一点因素,是 PHP 有最友好的社区,没有之一。不管是内外网,PHP 社区有极高的包容度。PHP 的讨论区很少有无谓的争吵,虚荣的推销。相反,PHP 社区有很多在其他圈子少见的谦逊与耐心 — 这也是我小孩喜欢网上讨论 PHP 的关键因素:当其他社区因为一个语法糖,一个框架,一个包争得面红耳赤时,经验丰富的 PHP 程序员却愿意放下姿态去回答几岁小孩的入门问题。进入 Zig ,Rust 等等社区,你会看到如邪教一般的传道与重写,我一个大人都有点承受不住。为了小孩的身心健康,我打心底更愿意小孩在 PHP 社区成长。

另外,不管喜不喜欢这门语言,少有人会否认 PHP 一直是一门及其实用且稳定的语言。尤其在 web 1.0 时代,PHP 绝对是指哪打哪的大杀器。哪怕是今天,快速迭代一个中小型全栈项目,很多人都会拿起 Laravel/ThinkPHP 。而现代化的 PHP 8 更是吸收了各家所长,OOP ,函数式,协程,可以说要什么有什么。更难能可贵的是在快速迭代的同时依然保持了高度的兼容性。对比乱成一锅粥的 Node/JS ,小孩写的 PHP 代码,不管是老语法,还是旧框架,往往都能运行,正向反馈频繁。我相信现在这些代码 5 年后依然能正常运行。

看到这里,您可能就明白我为什么说 PHP 有光明的未来了。后浪推前浪,世界终归是我们下一代的。当孩子们选择了 PHP ,他们怎么不会再一次为 PHP 带来阳光呢。

— 于 PHP 8.5 发布日 ]]>
记一次微信 access_token invalid credential, access_token is invalid or not latest tag:www.v2ex.com,2025-10-29:/t/1169261 2025-10-29T13:55:15Z 2025-10-29T18:19:25Z lyxxxh2 member/lyxxxh2 场景

多项目使用微信公众号access_token,每个项目的access_token不共享,就会:

{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: "} 

原因

"重复获取将导致上次获取的 access_token 失效。建议开发者使用中控服务器统一获取和刷新 access_token"

文档:https://developers.weixin.qq.com/doc/oplatform/developers/dev/AccessToken.html

工作这么多年,还没仔细看过微信文档。

解决

搞中控服务器麻烦,也懒着换成 reids 。

扩展包用的: w7corp/easywechat

默认用文件的缓存,保证用同个文件就行。

$app->getAccessToken()->getKey() $app->getAccessToken()->getToken() // 不同版本,方法不一样 $app->base->getAccessToken()->getTokenKey() $app->base->getAccessToken()->getToken() 

一开始我以为扩展包的坑,一个个排查,还去对比缓存文件的 token

最后一看微信文档,我擦 结案了。

]]>
重造 PHP -HTTP 性能检测,新增 List<int>、HashMap<K, V> tag:www.v2ex.com,2025-10-24:/t/1168205 2025-10-24T09:49:50Z 2025-10-23T17:49:50Z 2024 member/2024 https://github.com/php-any/origami

在访问 hello work 场景下,和 go http 标准库接近,2 万左右 qps 。 text

同时新增了更加便捷的查询

 $db = open("mysql", "root:root@/temp"); $db->ping(); Database\registerDefaultConnection($db); @Table("users") class User { public int $id; @Column("name") public string $userName; public int $age; public float $coin; @Column("create_at") public string $createAt; } $data = DB<User>(); echo "=== 基础查询 ===\n"; $user = $data->where("id = ?", 100)->first(); dump($user); 

除了 array 数组外,还有增强数组

$list = new List<int>(); $list->add(1); $list->add(2); $list->add(3); // 手动迭代 $list->rewind(); while ($list->valid()) { echo "索引: " . $list->key() . ", 值: " . $list->current() . "\n"; $list->next(); } 

KV 方式的泛型类

$map = new HashMap<string, int>(); $map->put("apple", 10); $map->put("banana", 20); $map->put("orange", 30); 
]]>
求助: PHP 错误,请高手帮我改写下面的 PHP 代码 tag:www.v2ex.com,2025-09-18:/t/1160327 2025-09-18T13:22:32Z 2025-09-18T05:22:32Z hwhtj member/hwhtj `<?php

$nowtime=time();

$pastsec = $nowtime - $_GET["t"];

if($pastsec<600) { exit; //10 分钟更新一次,时间可以自己调整 } ob_start(); //打开缓冲区 include("index.php"); $cOntent= ob_get_contents(); //得到缓冲区的内容 $content .= "\n<script language=Javascript src='http://www.v2ex.com/index/thumb.png' data-original="html.php?t=".$nowtime.""></script>"; //加上调用更新程序的代码

file_put_contents("index.html",$content); if (!function_exists("file_put_contents")) { function file_put_contents($fn,$fs) { $fp=fopen($fn,"w+"); fputs($fp,$fs); fclose($fp);
} } ?>`

以上代码用于生成 typecho 首页 index.html ,运行时提示错误: Warning: Undefined array key "t" in /www/onlineps.top/learn/html.php on line 3 求助高手帮我改写以上代码。

]]>
为什么现在 WEB3、区块链、钱包之类开始用 PHP 了 tag:www.v2ex.com,2025-09-12:/t/1158743 2025-09-12T03:10:19Z 2025-09-17T12:07:58Z fruitmonster member/fruitmonster 看到比较多的区块链、钱包之类远程工作都开始招 PHP 了,请问 PHP 是有什么优势了吗?

]]>
PHP 8.5 加入了 pipe 语法 tag:www.v2ex.com,2025-08-27:/t/1155173 2025-08-27T01:25:32Z 2025-08-27T19:52:20Z cj323 member/cj323 https://php.watch/versions/8.5/pipe-operator

$result = "Hello World" |> strtoupper(...) |> str_shuffle(...) |> trim(...); 

同样语法 JS 那边卡了很久,PHP 直接上了。

]]>
推荐一个优雅的 PHP http 请求工具,仿照了 py 的 requests tag:www.v2ex.com,2025-08-25:/t/1154669 2025-08-25T01:46:48Z 2025-08-24T09:46:48Z tg11 member/tg11 这是我某天突然想到的,python 的 requests 那么好用,为什么 php 要写的这么又臭又长呢?我就结合 claude code 写了一个 composer 包,完全仿照了 requests 模块。求轻喷,欢迎 star 、pr

github 地址 https://github.com/tg111/php-request

直接安装

composer require tg111/php-request 

示例

use PhpRequest\PhpRequest; // 简单的 GET 请求 $respOnse= PhpRequest::get('https://httpbin.org/get'); echo $response->text(); // 带参数的 GET 请求 $respOnse= PhpRequest::get('https://httpbin.org/get', [ 'key1' => 'value1', 'key2' => 'value2' ]); // POST 请求 $respOnse= PhpRequest::post('https://httpbin.org/post', [ 'username' => 'user', 'password' => 'pass' ]); // JSON POST 请求 $respOnse= PhpRequest::post('https://httpbin.org/post', [ 'name' => '张三', 'email' => 'zhangsan@example.com' ], [ 'headers' => ['Content-Type' => 'application/json'] ]); 

使用全局函数

$respOnse= requests_get('https://httpbin.org/get'); $respOnse= requests_post('https://httpbin.org/post', ['key' => 'value']); 

自定义请求头和身份验证

$respOnse= PhpRequest::get('https://httpbin.org/cookies', [], [ 'cookies' => [ 'session_id' => 'abc123456789', 'user_preference' => 'dark_mode' ] ]); # cookies $respOnse= PhpRequest::get('https://httpbin.org/cookies', [], [ 'cookies' => [ 'session_id' => 'abc123456789', 'user_preference' => 'dark_mode' ] ]); 

session 会话管理

会话允许在多个请求之间持久化 Cookie 、请求头和其他配置:

use PhpRequest\PhpRequest; // 创建会话 $session = PhpRequest::session() ->setHeaders([ 'Authorization' => 'Bearer token123', 'Accept' => 'application/json' ]) ->setCookies([ 'session_id' => 'session123' ]) ->setTimeout(60); // 使用会话进行多个请求 $profile = $session->get('/user/profile'); $settings = $session->get('/user/settings'); $updated = $session->post('/user/update', ['name' => '新名称']); 

响应对象

$respOnse= PhpRequest::get('https://httpbin.org/json'); // 获取响应内容 $text = $response->text(); // 原始文本内容 $data = $response->json(); // 解析 JSON 响应 $code = $response->getStatusCode(); // HTTP 状态码 // 检查响应状态 $success = $response->ok(); // 2xx 状态码为 true $isClientError = $response->isClientError(); // 4xx 状态码为 true $isServerError = $response->isServerError(); // 5xx 状态码为 true // 获取头部和元数据 $headers = $response->getHeaders(); $cOntentType= $response->getContentType(); $totalTime = $response->getTotalTime(); $url = $response->getUrl(); // 保存响应到文件 $response->save('/path/to/file.json'); 
]]>
大家好,我又來了,新作品 https://www.freetalkhub.com, PHP 开发 tag:www.v2ex.com,2025-08-17:/t/1153000 2025-08-17T11:41:29Z 2025-09-09T06:27:36Z mimiphp member/mimiphp 本人是 php 独立开发者,以前的话题 t/994939 被同行喷惨了。怎么说呢?本来我的话题都是发在 php 节点,本以为都是 php 自己的开发者讨论。但基于我个人观点,导致被评价为只会 CURD 实属以外。

本人是独立开发者,所以更趋向于了解整个开发流程的每个细节,毕竟除了自己,没有任何合作团队。 我认为说再多也没有拿作品说话比较实在。 本人以前就职于香港找换店和餐饮项目开发的公司。带领团队开发。但就是由于本人的观点是非主流观点,导致手下有部分人是不服从的。

由于 php 在主流程序开发界被嗤之以鼻多次,php 官方的开发团队也被强类型语言开发者参与主导。基于我本人自己的观点,感觉开发过于别扭。所以我自己以自己的作品为目标考虑符合自己的技术栈总结了一套开发思路。

本人就职期间原创开发了一个 PHP 开发框架,原名为 mimiphp ,先改名为 lowphp 由于 PHP-FPM 实在性能太差,基于我的本地电脑 AMD5600X wsl 下的 debian12 系统,也只能弄到 500 左右的并发,注意只是 echo 1;简单脚本测试结果。而如果是静态文件,通过 nginx 处理,可以达到 6 万并发。 所以我修改了框架核心,基于 swoole 的 cli 模式,支持了 swoole 协程模式。并且完整加载 mysql 数据和模板引擎渲染后的并发可以达到 5000 左右。我非常满意。

如果单独开启 redis 缓存可以达到 3 万左右并发。如果单独开启 apcu 缓存后可以达到 5 万并发。这实在是给力了。

其实我并不想跟同行过多争论,因为我发现一个现象,就是整个中文社区,其实任何争论都得不到一个比较好的结果。因为可能由于文化的影响,大家都会以自我的认知为中心,方圆几公里之内天下无敌的心态讽刺挖苦别人为目的,实际上根本不能心平气和的讨论任何话题。特别是程序开发行业从架构-语言-框架-甚至包括变量命名方式,都是毫无意义的讽刺挖苦。其实就是浪费时间罢了。对于技术的提升和理解都毫无用处。

我其实在这里发布过两个帖子,一个是关于 php8.3 的讨论。一个是 ffsou 搜索引擎的讨论,一个 2023 年,一个 2024 年。 我是直到刚才才看到 php8.3 讨论的帖子最后一个楼层居然认为我只是一个菜鸟。。这让我干了 20 年的程序员心里真的感到深深伤害。

其实我们这个行业,本身大环境就非常不好,本来我与香港的一个老板是以技术入股的方式合作,又由于前期没有资金聘请其他语言的程序员,而我又是自信能弄好项目上线的老程序员,所以也就是安心的处理代码了。

但我没有想到的是:2020 年到 2024 年底,这个香港老板一直给我反馈的都是无法正常盈利,只能勉强保本。直到 2024 年底,我从其他途径直到了真相,其实他盈利早过了 600 万以上。而且还把自己家人加入进来吃空饷等等原因,我还是决定主动辞职了。

又基于行业限制规则和法律风险的考虑,我重写了我自己的框架,目前是独立开发者身份。然后考虑直接走国际路线,与国外的程序员沟通交流。发现真的行业文化差异实在太大了。

我希望我们作为简体中文的程序员,应该要自信,和睦相处,多与同行技术交流,而不是讽刺挖苦。

当然,国外同样是以作品说话。目前由于金融行业涉及到严格的资金来源追溯问题,找换店已经不行了,但其他方向,特别是 AI 使用上,国外几乎每天都有几十上百个 Saas 项目发布。当然其中也有我一份功劳,赚了点小钱。

所以基于以上的前提,我想说一下我这个 https://www.freetalkhub.com 是参考了 reddit 和 discuz 以及其他社区后,用我新开发的 lowphp 基于 swoole 高并发开发的 php 框架完成。

其中前端采用到了 vue3.0 的 cdn 模式,以及 pjax 伪单页模式。目前收录和用户体验都非常好。

当然,这是一个试运行站点,主要目的还是宣传为主。 但技术栈我是想弱化前端工程化的主流思想。欢迎体验。

而后端 php 一直在更新,我也采用了最新的 php8.4 版本为核心。我希望用我自己的实践和作品,为 php 的开发环境做一个贡献。希望大家参与讨论。前提是站在平等的位置上。不过你讽刺挖苦也无所谓,对于我来说,早已经锻炼出了死猪不怕开水烫的本事。

]]>
laravel 和 thinkphp 选择哪个? tag:www.v2ex.com,2025-07-26:/t/1147927 2025-07-26T16:26:47Z 2025-08-30T18:55:29Z sxszzhrrt member/sxszzhrrt 202505 最新调研: PHP Opcode 加密混淆哪家强? tag:www.v2ex.com,2025-05-26:/t/1134248 2025-05-26T00:47:27Z 2025-05-29T13:22:10Z heguangyu5 member/heguangyu5 近来看到有网友咨询 PHP 源码保护、防破解的问题, 我也很久没有了解了. 借机更新一下自己的认识, 了解了解市场现状.

PHP 源码保护方案有多种,本文说的是对 opcode 进行加密混淆的方案.一般认为,这种方案的加密强度较强,保护程度也较高.

本文调研了两款 PHP 源码加密产品.调研过程中关注两个重点:

  1. 如何拿到加密混淆后的 opcode.
  2. opcode 能反编译回 PHP 代码吗?

为了不对产品本身造成不好的影响, 我们称这两款产品分别为 AAABBB.

AAA 是国内产品,号称 "最佳 PHP 源代码加密编译器".

BBB 是国外产品,号称 "the most widely trusted PHP protection tool".

先来看 AAA.

AAA

首先,我们需要一段 PHP 代码作为被保护对象.这里选取一个对 PDO 类进行简易封装的 Db 类. 完整源码见: Db.php

然后,使用 AAA 试用版Db.php 加密, 加密时选择 PHP 版本 8.0,加密完成后下载回来,然后将对应的 AAA_loader_80_nts.so也下载回来.

php 的 opcache 扩展有个方便的功能,可以把 php 代码的 opcode dump 出来.

$ ~/tmp/php-8.0.30/bin/php -d 'opcache.enable_cli=1' -d 'opcache.opt_debug_level=0x10000' ../Db.php $_main: ; (lines=1, args=0, vars=0, tmps=0) ; (before optimizer) ; /home/hgy/Downloads/php-opcode-test/Db.php:1-97 ; return [] RANGE[0..0] 0000 RETURN int(1) OurBlog_Db::__construct: ; (lines=36, args=0, vars=0, tmps=18) ; (before optimizer) ; /home/hgy/Downloads/php-opcode-test/Db.php:9-17 ; return [] RANGE[0..0] 0000 V1 = NEW 3 string("PDO") 0001 INIT_FCALL 1 96 string("getenv") 0002 SEND_VAL string("DB_HOST") 1 0003 V2 = DO_ICALL 0004 T3 = CONCAT string("mysql:host=") V2 0005 T4 = CONCAT T3 string(";port=") 0006 INIT_FCALL 1 96 string("getenv") 0007 SEND_VAL string("DB_PORT") 1 0008 V5 = DO_ICALL 0009 T6 = CONCAT T4 V5 0010 T7 = CONCAT T6 string(";dbname=") 0011 INIT_FCALL 1 96 string("getenv") 0012 SEND_VAL string("DB_DATABASE") 1 0013 V8 = DO_ICALL 0014 T9 = CONCAT T7 V8 0015 T10 = CONCAT T9 string(";charset=utf8") 0016 SEND_VAL_EX T10 1 // 由于 V2EX 限制主题内容不能超过 20000 个字符,这里删除了余下的 opcode 

现在我们拿到了 Db.php 未加密混淆的 opcode.

再来看看 AAA 加密混淆过的 Db-AAA.php 的 opcode 长什么样. 将 AAA_loader_80_nts.so 加到 php.ini 里并配置好.

~/tmp/php-8.0.30/bin/php -d 'opcache.enable_cli=1' -d 'opcache.opt_debug_level=0x1000' Db-AAA.php 

什么输出都没有.

可以理解,应该是 AAA_loader_80_nts.so 来接管处理 Db-AAA.php, opcache 扩展不起作用了.

那还有什么办法能拿到 opcode 吗?可以用 phpdbg.

$ ~/tmp/php-8.0.30/bin/phpdbg -p* Db-AAA.php function name: (null) L1-97 {main}() /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php - 0x719eb1e09cb0 + 1 ops L97 #0 FETCH_DIM_W<-1> 1 NEXT user class: OurBlog_Db 10 methods: __construct, __clone, getInstance, fetchOne, fetchRow, fetchAll, fetchCol, insert, update, __call function name: __construct L9-17 OurBlog_Db::__construct() /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php - 0x719eb1e065a0 + 36 ops L11 #0 NEW<3> "PDO" @0 L2147483647 #1 YIELD<1> "VTM]\\V" L1073741823 #2 PRE_INC "ssipe " L12 #3 DO_FCALL @1 L12 #4 FETCH_DIM_W "mysql:host=" @1 ~2 L12 #5 FETCH_DIM_W ~2 ";port=" ~1 L2147483647 #6 MATCH_ERROR<1> "VTM]\\V" L1073741823 #7 JMPZ_EX "ssihe " L12 #8 DO_FCALL @3 L12 #9 FETCH_DIM_W ~1 @3 ~2 L12 #10 FETCH_DIM_W ~2 ";dbname=" ~1 L2147483647 #11 MATCH_ERROR<1> "VTM]\\V" L1073741823 #12 JMPZ_EX "usmru~ eyu" L12 #13 DO_FCALL @3 L12 #14 FETCH_DIM_W ~1 @3 ~2 L12 #15 FETCH_DIM_W ~2 ";charset=utf8" ~1 // 由于 V2EX 限制主题内容不能超过 20000 个字符,这里删除了余下的 opcode [Script ended normally] 

不过 phpdbg 输出的 opcode 没有 opcache 输出的易读,比如最后一个函数OurBlog_Db::__call()里的call_user_func_array()没显示完整,只显示了个call_user_func_ar.

有没有办法让 php-8.0.30 的 phpdbg 输出像 opcache 那种样式的 opcode 呢?

这里只所以要强调 php-8.0.30 的 phpdbg , 是因为 php-8.3 的 phpdbg 输出的 opcode 已经和 opcache 风格统一了.

我们可以对 phpdbg 稍做修改,把 opcache 输出 opcode 的代码用在 phpdbg 里,这样就可以了.

给 phpdbg 新加一个参数-p**,来调用 opcache 里的 dump 相关代码.

$ ~/tmp/php-8.0.30/bin/phpdbg -p** Db-AAA.php $_main: ; (lines=1, args=0, vars=0, tmps=0) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:1-97 ; return [] 0000 FETCH_DIM_W int(1) NEXT OurBlog_Db::__construct: ; (lines=36, args=0, vars=0, tmps=4, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:9-17 ; return [class] RANGE[--..136834057266072] 0000 V0 = NEW 3 string("PDO") 0001 YIELD (function) string("VTM]\V") 0002 PRE_INC string("ssipe") 0003 V1 = DO_FCALL 0004 T2 = FETCH_DIM_W string("mysql:host=") V1 0005 T1 = FETCH_DIM_W T2 string(";port=") 0006 MATCH_ERROR string("VTM]\V") 0007 JMPZ_EX string("ssihe") 0008 V3 = DO_FCALL 0009 T2 = FETCH_DIM_W T1 V3 0010 T1 = FETCH_DIM_W T2 string(";dbname=") 0011 MATCH_ERROR string("VTM]\V") 0012 JMPZ_EX string("usmru~eyu") 0013 V3 = DO_FCALL 0014 T2 = FETCH_DIM_W T1 V3 0015 T1 = FETCH_DIM_W T2 string(";charset=utf8") 0016 OP_242 T1 0017 BOOL_XOR string("VTM]\V") 0018 FE_RESET_RW string("ssimy ") 0019 V1 = DO_FCALL 0020 SEND_USER V1 2 0021 MATCH_ERROR string("VTM]\V") 0022 OP_244 string("usmfuy kxt") 0023 V1 = DO_FCALL 0024 SEND_USER V1 3 0025 DO_FCALL 0026 FETCH_DIM_W string("pdo") 0027 FETCH_DIM_W V0 NEXT 0028 EXT_STMT T0 string("FTY") 0029 CASE T0 string("AVMw@TS)FGLU") 0030 T0 = FETCH_DIM_W string("PDO") string("ATTR_ERRMODE") 0031 SR T0 0032 T0 = FETCH_DIM_W string("PDO") string("ERRMODE_EXCEPTION") 0033 GET_CLASS T0 0034 DO_FCALL 0035 FETCH_DIM_W null NEXT OurBlog_Db::__clone: ; (lines=1, args=0, vars=0, tmps=0) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:19-20 ; return [undef, ref, class] RANGE[--..136834057268056] 0000 FETCH_DIM_W null NEXT OurBlog_Db::getInstance: ; (lines=9, args=0, vars=0, tmps=2, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:22-28 ; return [] RANGE[--..2207613190024] 0000 T1 = FETCH_DIM_W string("instance") NEXT 0001 T0 = FETCH_DIM_W T1 null 0002 JMPZ T0 0007 0003 V0 = NEW 0 (self) (exception) 0004 DO_FCALL 0005 FETCH_DIM_W string("instance") NEXT 0006 FETCH_DIM_W V0 NEXT 0007 T0 = FETCH_DIM_W string("instance") NEXT 0008 FETCH_DIM_W T0 NEXT OurBlog_Db::fetchOne: ; (lines=13, args=2, vars=3, tmps=1, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:30-35 ; return [ref, class] RANGE[--..6262542] 0000 CV0($Sh40) = RECV 1 0001 CV1($Sh41) = RECV_INIT 2 array(...) 0002 OP_204 T3 string("FTY") 0003 FETCH_DIM_W T3 string("AA\GXRD") 0004 SEND_USER CV0($Sh40) 1 0005 V3 = DO_FCALL 0006 CV2($Sh42) = FETCH_DIM_W V3 NEXT 0007 BIND_LEXICAL (ref) CV2($Sh42) string("TK\TLTD") 0008 SEND_USER CV1($Sh41) 1 0009 DO_FCALL 0010 OP_216 CV2($Sh42) string("TTMU_cN,Q_V") 0011 V3 = DO_FCALL 0012 FETCH_DIM_W V3 NEXT OurBlog_Db::fetchRow: ; (lines=15, args=3, vars=4, tmps=1, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:37-42 ; return [class] RANGE[--..136834057270096] 0000 CV0($Sh43) = RECV 1 0001 CV1($Sh44) = RECV_INIT 2 array(...) 0002 CV2($Sh45) = RECV_INIT 3 zval(type=11) 0003 DECLARE_LAMBDA_FUNCTION T4 string("FTY") 0004 OP_216 T4 string("AA\GXRD") 0005 SEND_USER CV0($Sh43) 1 0006 V4 = DO_FCALL 0007 CV3($Sh46) = FETCH_DIM_W V4 NEXT 0008 SWITCH_STRING CV3($Sh46) 0008 string("TK\TLTD") 0009 SEND_USER CV1($Sh44) 1 0010 DO_FCALL 0011 BW_XOR CV3($Sh46) string("_\LVH") 0012 SEND_USER CV2($Sh45) 1 0013 V4 = DO_FCALL 0014 FETCH_DIM_W V4 NEXT OurBlog_Db::fetchAll: ; (lines=15, args=3, vars=4, tmps=1, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:44-49 ; return [class] RANGE[--..136834057271416] 0000 CV0($Sh47) = RECV 1 0001 CV1($Sh48) = RECV_INIT 2 array(...) 0002 CV2($Sh49) = RECV_INIT 3 zval(type=11) 0003 OP_204 T4 string("FTY") 0004 OP_246 T4 string("AA\GXRD") 0005 SEND_USER CV0($Sh47) 1 0006 V4 = DO_FCALL 0007 CV3($Sh410) = FETCH_DIM_W V4 NEXT 0008 OP_220 CV3($Sh410) string("TK\TLTD") 0009 SEND_USER CV1($Sh48) 1 0010 DO_FCALL 0011 YIELD_FROM CV3($Sh410) string("WPMT^aM,") 0012 SEND_USER CV2($Sh49) 1 0013 V4 = DO_FCALL 0014 FETCH_DIM_W V4 NEXT OurBlog_Db::fetchCol: ; (lines=15, args=2, vars=3, tmps=1, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:51-56 ; return [ref, class] RANGE[--..136834057272704] 0000 CV0($Sh411) = RECV 1 0001 CV1($Sh412) = RECV_INIT 2 array(...) 0002 OP_222 T3 string("FTY") 0003 FETCH_DIM_W T3 string("AA\GXRD") 0004 SEND_USER CV0($Sh411) 1 0005 V3 = DO_FCALL 0006 CV2($Sh413) = FETCH_DIM_W V3 NEXT 0007 CASE CV2($Sh413) string("TK\TLTD") 0008 SEND_USER CV1($Sh412) 1 0009 DO_FCALL 0010 BIND_LEXICAL (ref) CV2($Sh413) string("WPMT^aM,") 0011 T3 = FETCH_DIM_W string("PDO") string("FETCH_COLUMN") 0012 OP_231 T3 0013 V3 = DO_FCALL 0014 FETCH_DIM_W V3 NEXT OurBlog_Db::insert: ; (lines=55, args=2, vars=7, tmps=5, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:58-74 ; return [class] RANGE[--..136834057274120] 0000 CV0($Sh414) = RECV 1 0001 CV1($Sh415) = RECV 2 0002 JMPNZ CV1($Sh415) 0011 0003 CONCAT T7 string("FTY") 0004 SWITCH_STRING T7 0004 string("RA][") 0005 T8 = DECLARE_ANON_CLASS string("INSERT INTO `") 0006 T8 = DECLARE_ANON_CLASS T8 CV0($Sh414) 0007 T7 = FETCH_DIM_W T8 string("` VALUES (NULL)") 0008 OP_228 T7 0009 DO_FCALL 0010 FETCH_DIM_W null NEXT 0011 CV2($Sh416) = FETCH_DIM_W array(...) NEXT 0012 DEFINED string("PKKVIJ%]A") 0013 SEND_USER CV1($Sh415) 1 0014 V8 = DO_FCALL 0015 V7 = FETCH_DIM_W V8 NEXT 0016 FETCH_DIM_W V7 CV3($Sh417) 0017 T9 = DECLARE_ANON_CLASS string("`") 0018 T9 = DECLARE_ANON_CLASS T9 CV3($Sh417) 0019 T8 = FETCH_DIM_W T9 string("`") 0020 FETCH_DIM_W CV2($Sh416) NEXT 0021 FETCH_DIM_W T8 NEXT 0022 FETCH_DIM_W NEXT 0023 FE_FREE V7 0024 BW_NOT string("X^I[VDD") 0025 FETCH_OBJ_IS THIS string("") 0026 SEND_USER CV2($Sh416) 2 0027 V7 = DO_FCALL 0028 FETCH_DIM_W CV2($Sh416) V7 0029 MUL string("BMKhBEQ%EF") ")30 FE_RESET_RW string(" 0031 T8 = FETCH_DIM_W CV1($Sh415) NEXT 0032 T7 = FETCH_DIM_W T8 int(1) 0033 SEND_USER T7 2 0034 V8 = DO_FCALL 0035 CV4($Sh418) = FETCH_DIM_W V8 string("?") 0036 T8 = DECLARE_ANON_CLASS string("INSERT INTO `") 0037 T8 = DECLARE_ANON_CLASS T8 CV0($Sh414) 0038 T8 = DECLARE_ANON_CLASS T8 string("` (") 0039 T8 = DECLARE_ANON_CLASS T8 CV2($Sh416) 0040 T8 = DECLARE_ANON_CLASS T8 string(") VALUES (") 0041 T8 = DECLARE_ANON_CLASS T8 CV4($Sh418) 0042 CV5($Sh419) = FETCH_DIM_W T8 string(")") 0043 CONCAT T7 string("FTY") 0044 BIND_LEXICAL (ref) T7 string("AA\GXRD") 0045 SEND_USER CV5($Sh419) 1 0046 V7 = DO_FCALL 0047 CV6($Sh420) = FETCH_DIM_W V7 NEXT 0048 OP_216 CV6($Sh420) string("TK\TLTD") 0049 MATCH_ERROR string("SAKWMW!HG]C") 0050 SEND_USER CV1($Sh415) 1 0051 V7 = DO_FCALL 0052 SEND_USER V7 1 0053 DO_FCALL 0054 FETCH_DIM_W null NEXT OurBlog_Db::update: ; (lines=44, args=3, vars=7, tmps=4, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:76-90 ; return [class] RANGE[--..136834057277472] 0000 CV0($Sh421) = RECV 1 0001 CV1($Sh422) = RECV 2 0002 CV2($Sh423) = RECV_INIT 3 string("1") 0003 JMPNZ CV1($Sh422) 0008 0004 V7 = NEW 1 string("Exception") 0005 OP_226 string("update with empty row is not allowed!") 0006 DO_FCALL 0007 FETCH_DIM_W V7 NEXT 0008 CV3($Sh424) = FETCH_DIM_W array(...) NEXT 0009 MUL string("PKKVIJ%]A") 0010 SEND_USER CV1($Sh422) 1 0011 V8 = DO_FCALL 0012 V7 = FETCH_DIM_W V8 NEXT 0013 FETCH_DIM_W V7 CV4($Sh425) 0014 T9 = DECLARE_ANON_CLASS string("`") 0015 T9 = DECLARE_ANON_CLASS T9 CV4($Sh425) 0016 T8 = FETCH_DIM_W T9 string("` = ?") 0017 FETCH_DIM_W CV3($Sh424) NEXT 0018 FETCH_DIM_W T8 NEXT 0019 FETCH_DIM_W NEXT 0020 FE_FREE V7 0021 FETCH_FUNC_ARG (global) string("X^I[VDD") 0022 OP_205 string("") 0023 SEND_USER CV3($Sh424) 2 0024 V7 = DO_FCALL 0025 FETCH_DIM_W CV3($Sh424) V7 0026 T8 = DECLARE_ANON_CLASS string("UPDATE `") 0027 T8 = DECLARE_ANON_CLASS T8 CV0($Sh421) 0028 T8 = DECLARE_ANON_CLASS T8 string("` SET ") 0029 T8 = DECLARE_ANON_CLASS T8 CV3($Sh424) 0030 T8 = DECLARE_ANON_CLASS T8 string(" WHERE ") 0031 CV5($Sh426) = FETCH_DIM_W T8 CV2($Sh423) 0032 POST_INC T7 string("FTY") 0033 BW_XOR T7 string("AA\GXRD") 0034 SEND_USER CV5($Sh426) 1 0035 V7 = DO_FCALL 0036 CV6($Sh427) = FETCH_DIM_W V7 NEXT 0037 OP_220 CV6($Sh427) string("TK\TLTD") 0038 FETCH_FUNC_ARG string("SAKWMW!HG]C") 0039 SEND_USER CV1($Sh422) 1 0040 V7 = DO_FCALL 0041 SEND_USER V7 1 0042 DO_FCALL 0043 FETCH_DIM_W null NEXT OurBlog_Db::__call: ; (lines=10, args=2, vars=2, tmps=2, dynamic, irreducable, extended_stmt, extended_fcall) ; /home/hgy/Downloads/php-opcode-test/AAA/Db-AAA.php:92-95 ; return [!ref, class] RANGE[--..109071675059458] 0000 CV0($Sh428) = RECV 1 0001 CV1($Sh429) = RECV 2 0002 DECLARE_LAMBDA_FUNCTION T3 string("FTY") 0003 T2 = FETCH_DIM_W T3 NEXT 0004 T2 = DECLARE_ANON_CLASS CV0($Sh428) 0005 NEW 0 string("call_user_func_array") T2 0006 SEND_UNPACK CV1($Sh429) 0007 FETCH_DIM_W NEXT 0008 V2 = DO_FCALL 0009 FETCH_DIM_W V2 NEXT [Script ended normally] 

好,现在我们拿到了 AAA 加密混淆过的 opcode.

接下来就要把这些 opcode 给反编译成 PHP 代码. 这可不好弄. 不过好在有 AI 大模型,是时候展现 AI 真正的实力了!

以下是 Google Gemini 反编译的结果:

@see https://g.co/gemini/share/148782890130

大家可以自行对比一下,反正我是被震惊到了!

也有可能 Db.php 的代码较为常见,被 AI 蒙对了.

腾讯元宝 DeepSeek-R1 反编译的结果如下:

@see https://yuanbao.tencent.com/bot/app/share/chat/KUiqoTNjZalJ

AAA 的调研我们先到这里.

AAA 留给我们的问题是, opcode 到底能不能程序化地反编译成 PHP 代码.

BBB

去 BBB 的网站上把 BBB 的 encoder 试用版 和 loader 都下载回来.

BBB 的 encoder 没有 php-8.0 版本的, 那我们就选最高可用版本 php-8.3 的.

同样对 Db.php 进行加密, 得到加密后的文件 Db-BBB.php

./BBB_encoder_evaluation/BBB_encoder.sh -C -x86-64 -83 ../Db.php -o Db-BBB.php 

接下来我们用同样的办法尝试拿到 Db-BBB.php 的 opcode.

BBB_loader_lin_8.3.so 加到 php.ini 里配置好.

先用 opcache 尝试一下:

$ ~/tmp/php-8.3.21/bin/php -d 'opcache.enable_cli=1' -d 'opcache.opt_debug_level=0x1000' Db-BBB.php 

没有任何输出.

再用 phpdbg 尝试一下:

$ ~/tmp/php-8.3.21/bin/phpdbg -p* Db-BBB.php Segmentation fault (core dumped) 

直接 segfault 了.

我们使用 gdb 来调试一下.

$ gdb ~/tmp/php-8.3.21/bin/phpdbg (gdb) b phpdbg_compile_file (gdb) r -p* ../Db.php (gdb) n (gdb) 250 ret = PHPDBG_G(compile_file)(file, type); (gdb) 251 if (ret == NULL) { (gdb) set print pretty on (gdb) p *ret $1 = { type = 2 '\002', arg_flags = "\000\000", fn_flags = 100663296, function_name = 0x0, scope = 0x0, prototype = 0x0, num_args = 0, required_num_args = 0, arg_info = 0x0, attributes = 0x0, run_time_cache__ptr = 0x0, T = 0, cache_size = 0, last_var = 0, last = 1, opcodes = 0x7ffff5002450, static_variables_ptr__ptr = 0x0, static_variables = 0x0, vars = 0x0, refcount = 0x7ffff5004008, last_live_range = 0, last_try_catch = 0, live_range = 0x0, try_catch_array = 0x0, filename = 0x7ffff505e3c0, line_start = 1, line_end = 97, doc_comment = 0x0, last_literal = 1, num_dynamic_func_defs = 0, literals = 0x7ffff5002470, dynamic_func_defs = 0x0, reserved = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } (gdb) c Continuing. ... [Script ended normally] [Inferior 1 (process 187677) exited normally] (gdb) r -p* Db-BBB.php (gdb) n (gdb) 250 ret = PHPDBG_G(compile_file)(file, type); (gdb) 251 if (ret == NULL) { (gdb) p *ret $2 = { type = 2 '\002', arg_flags = "\000\000", fn_flags = 100663296, function_name = 0x0, scope = 0x0, prototype = 0x0, num_args = 0, required_num_args = 0, arg_info = 0x0, attributes = 0x0, run_time_cache__ptr = 0x7ffff5004030, T = 1, cache_size = 0, last_var = 0, last = 0, opcodes = 0x1, static_variables_ptr__ptr = 0x0, static_variables = 0x0, vars = 0x0, refcount = 0x7ffff5004020, last_live_range = 0, last_try_catch = 0, live_range = 0x0, try_catch_array = 0x0, filename = 0x0, line_start = 1, line_end = 0, doc_comment = 0x0, last_literal = 0, num_dynamic_func_defs = 0, literals = 0x0, dynamic_func_defs = 0x0, reserved = {0x0, 0x0, 0x0, 0x7ffff5081460, 0x0, 0x0} } (gdb) quit 

对比两次 p *ret 不难发现, 未加密的 Db.php:

opcodes = 0x7ffff5002450, reserved = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}

已加密的 Db-BBB.php:

opcodes = 0x1, reserved = {0x0, 0x0, 0x0, 0x7ffff5081460, 0x0, 0x0}

0x1 显然不是一个有效的内存地址,现在 opcode 在哪儿,不好找了.

再次 gdb 关注一下 zend_compile_filezend_execute_ex:

$ gdb ~/tmp/php-8.3.21/bin/php (gdb) watch zend_compile_file (gdb) watch zend_execute_ex (gdb) r Db-BBB.php ... (gdb) Continuing. Hardware watchpoint 1: zend_compile_file Old value = (zend_op_array *(*)(zend_file_handle *, int)) 0x555555786ae0 <phar_compile_file> New value = (zend_op_array *(*)(zend_file_handle *, int)) 0x7ffff40e5041 0x00007ffff40571d4 in ?? () from /home/hgy/Downloads/php-opcode-test/BBB/BBB/BBB_loader_lin_8.3.so (gdb) Continuing. Hardware watchpoint 2: zend_execute_ex Old value = (void (*)(zend_execute_data *)) 0x55555596adf0 <execute_ex> New value = (void (*)(zend_execute_data *)) 0x7ffff40f2784 0x00007ffff40571de in ?? () from /home/hgy/Downloads/php-opcode-test/BBB/BBB/BBB_loader_lin_8.3.so 

可以看到 BBB_loader_lin_8.3.so 既接管了 zend_compile_file, 又接管了 zend_execute_ex. 这样 opcodes 就成了个黑盒子, 我们既不知道在哪儿,也不知道内容.

这怎么办呢? 是不是说 BBB 这个产品加密强度非常强,值得信赖呢?

别急,网上搜索一下. 很快就找到了这个 https://dezender.xyz/

在 DECODERS 菜单里,就有 BBB PHP 8.3, 可以在线试用,只不过只能 decode 10 行,我们试一下.

成功解密.

<?php /* * @ https://dezender.xyz - BBB Decoder Online * @ Decoder version: 3.0.0 * @ Release: 2025/04/09 */ class OurBlog_Db { protected static $instance = null; protected $pdo = null; protected function __construct(){ $this->pdo = new PDO("mysql:host=" . getenv("DB_HOST") . ";port=" . getenv("DB_PORT") . ";dbname=" . getenv("DB_DATABASE") . ";charset=utf8", getenv("DB_USER"), getenv("DB_PASSWORD")); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } private function __clone(){ } // This is the demo version. Demo version decode 10 lines only. 

简直太强了!!!

总结

  1. AAA 可以比较容易拿到加密混淆过的 opcodes, 但没有成熟可用的反编译工具.
  2. BBB 不容易拿到加密混淆过的 opcodes, 但有成熟的反编译工具.
]]>
有做过基于 webrtc 技术的多人视频会议系统的吗 tag:www.v2ex.com,2025-04-29:/t/1128998 2025-04-29T14:01:38Z 2025-05-01T18:55:06Z tangknox1 member/tangknox1
多人视频会议:主持人(视频直播)+ 其他人多人语音连麦互动,或者 主播直播 + 多人语音连麦与主播互动。 ]]>
2025 年 PHP 路在何方 tag:www.v2ex.com,2025-04-28:/t/1128749 2025-04-28T14:55:52Z 2025-04-27T22:54:52Z Tinywan member/Tinywan 求助 CodeIgniter 输出的 html 格式很乱,缩进乱七八糟的。。。 tag:www.v2ex.com,2025-04-28:/t/1128732 2025-04-28T13:26:59Z 2025-04-27T21:26:59Z TESTFLIGHT2021 member/TESTFLIGHT2021 请问这怎么解决啊? ]]> 有个关于 PHP 的小疑惑 tag:www.v2ex.com,2025-04-26:/t/1128194 2025-04-26T08:09:13Z 2025-05-05T12:46:22Z seansong member/seansong
"is_completed": 0
"is_completed": "0"
"is_completed": false

同一个接口返回的完全一样的同一份数据,为什么每次请求,得到的数据类型都不一样呢,而且是随机的,有时候接口返回的数组中,不同元素里面的这个字段,都会出现不一样的类型,什么场景下会出现这种情况,个别程序员搞成这样的,还是 php 生态中就是这样

弱类型,好像能理解,但就是好奇罢了 ]]>
workman 与阿里云实时语音通信的问题。 tag:www.v2ex.com,2025-04-23:/t/1127661 2025-04-23T17:33:31Z 2025-04-24T17:43:43Z awanganddong member/awanganddong /** * 项目 socket 连接时触发(一次) * 当客户端与 Workerman 建立连接时(TCP 三次握手完成后)触发的回调函数 */ public static function onConnect($client_id) { // 定义连接函数 $cOnnectWs= function () { $ws = new AsyncTcpConnection('ws://dashscope.aliyuncs.com/api-ws/v1/inference'); $ws->headers = [ "Authorization" => "Bearer " . getenv("DASHSCOPE_API_KEY"), ]; $ws->transport = "ssl"; // 连接成功回调 $ws->OnConnect= function ($ws) { self::$aliWs = $ws; echo "connected success:" . $ws->id . "\n"; }; // 当收到消息时 $ws->OnMessage= function ($ws, $data) { var_dump("ali 返回消息", $data); $msg = json_decode($data, true); $channel = self::$sendWsChan; Coroutine::create( function () use ($channel, $msg) { $channel->push($msg); }, ); }; // 连接关闭时进行重连 $ws->OnClose= function ($ws) { echo "连接关闭,尝试重新连接...\n"; self::$aliWs = null; $ws->reConnect(1); }; $ws->OnError= function ($ws) { echo "错误输出" . $ws->error; }; $ws->connect(); }; //定时器触发 if (self::$aliWs) { var_dump("发送事件"); self::$aliWs->send(json_encode($data)); }

初次建立长连接可以发送成功,但是如果阿里云长连接断线重连几次后,发送事件,在 onMessage 里边没有响应。不明白为什么出现这种情况。var_dump("发送事件"); 可以打印数据。但是 onMessage 不存在数据。

]]>
目前 PHP 中比较好用的工作流引擎有哪些? tag:www.v2ex.com,2025-04-18:/t/1126479 2025-04-18T07:18:46Z 2025-05-06T21:49:52Z xmlf member/xmlf
各位大佬帮忙推荐推荐。。。你们平时都用什么工作流引擎? ]]>
有老哥熟悉 OpenCart 的吗? tag:www.v2ex.com,2025-04-10:/t/1124523 2025-04-10T09:06:02Z 2025-04-10T12:58:02Z carl92 member/carl92 开源 PHP Composer 私有 package 管理平台 tag:www.v2ex.com,2025-04-08:/t/1123931 2025-04-08T05:37:40Z 2025-04-07T21:37:40Z akagishigeru member/akagishigeru 在做的一些项目的 package 都是用私有包分发的,用户使用私有包的授权码获取更新包。当然这个项目的主要功能是分发包,而不是保护包的源代码。

感兴趣的可以关注下 😂 Packvault 开源地址

做一些 PHP 项目 然后给用户做分发还是挺有用的

]]>
推荐个好用的集成环境 tag:www.v2ex.com,2025-04-06:/t/1123546 2025-04-06T09:51:52Z 2025-04-06T14:09:14Z flowerwow0316 member/flowerwow0316 https://flyenv.com/ 第一次见这么叼的,能什么都集成在一起的。

]]>
phpinfo(); logo 变成了绿色的大象 tag:www.v2ex.com,2025-04-01:/t/1122589 2025-04-01T07:34:00Z 2025-04-01T08:13:09Z hukei member/hukei PHP 项目有类似前端 monorepo 的概念吗? tag:www.v2ex.com,2025-03-09:/t/1117090 2025-03-09T13:45:55Z 2025-03-10T15:08:18Z tlerbao member/tlerbao
有前端 monorepo 的概念吗哈哈 ]]>
想用 PHP 做微服务开发,有偿求指导 tag:www.v2ex.com,2025-03-05:/t/1116197 2025-03-05T15:52:24Z 2025-03-07T19:42:23Z fan88 member/fan88 目前技术栈是 thinkphp8 + swoole ,现在客户有要求不准我们做单体应用,必须要做微服务开发。 对微服务的开发没什么经验,想咨询有经验的师傅指指门道,有偿 同时,我也考虑部分的服务进行外包,欢迎有经验的师傅来联系

]]>
PHP 语言已经过气了吗 tag:www.v2ex.com,2025-02-18:/t/1112469 2025-02-18T19:12:07Z 2025-03-14T14:16:47Z AndrewHenry member/AndrewHenry 国内 PHP 卷王是鸟哥 tag:www.v2ex.com,2025-01-30:/t/1108309 2025-01-30T00:30:17Z 2025-02-26T10:20:56Z zhouyin member/zhouyin 最近学了 python 原生协程 async await 以及 asyncio 库

回头重新看了 php 协程 发现 php 协程实在太垃圾了 好像有个官方文档 提供了大量示例 协程也可以取消 但它是把所有 job 放入一个队列 取消就是从队列删除 实在太垃圾了 跟 python asyncio 比都不能比 python asyncio 可以直接把函数创建为 task 然后超时的话 在主控制函数里直接 task.cancel()

php 的协程代码也是看起来太啰嗦 一团糟

这几年 php 的份额不断被 js go 蚕食 php 要推出 jit 主要作者是鸟哥 其实鸟哥是国内 php 卷王 必须要维持自己的生存 不断给 php 进化 不然 php 被抛弃了 被扫进历史垃圾堆了 他的日子也要不好过了

]]>
mysql update 更新失败的原因。 tag:www.v2ex.com,2025-01-15:/t/1105356 2025-01-15T11:24:45Z 2025-01-15T13:37:36Z awanganddong member/awanganddong 后台有一个批量操作的功能。

用户审核通过,然后给他的邀请人加优惠价。

伪代码 foreach(users as user){ //通过审核(事务保证) // 给邀请人加优惠卷(事务保证) } 

现在出现的问题是用户加优惠价这个过程,对用户信息更新优惠卷总数失败。

给用户加优惠卷有 2 个插入操作,一个更新操作。

刚才进行批量操作,执行了 20 个用户,其中几个 update 操作失败。所以对这个问题没想明白,mysql rr 级别。

]]>
PHP 程序员是往运维还是前端发展作为拓展呢 tag:www.v2ex.com,2025-01-01:/t/1101729 2025-01-01T01:57:24Z 2025-01-01T13:59:09Z hkui2012 member/hkui2012 php 做了七八年了,之前没分离的时候,jquery 一把梭,现在前端技术 都 vue,nuxt 等前后端分离的那一套,很久没写前端了, 会点 go,公司之前转 java,写过一点,后来公司放弃了,又重回 php 了,运维也懂一点

如果想继续待下去,是学前端还是运维呢 或者卷其它,目前基本的运维会,k8s 懂一些

]]>
求大佬解决一下一个问题 tag:www.v2ex.com,2024-11-27:/t/1093198 2024-11-27T11:50:07Z 2024-11-27T14:34:19Z SEoSean member/SEoSean 我需要 利用 php 来获取访问的蜘蛛 需要在其他页面调用 代码应该怎么写? 求大佬给一个参考 谢谢

]]>
[2024-11-21] PHP 8.4 Released! tag:www.v2ex.com,2024-11-25:/t/1092397 2024-11-25T06:11:17Z 2024-11-27T08:51:44Z coderzhangsan member/coderzhangsan RT

本以为这个版本之后,下个版本会直升 PHP 9.0 ,带来一些新的东西,没想到还是小版本 PHP 8.5 ,虽然 PHP 正在没落,但还是希望她能够越来越完善。

PHP 8.4 Release

]]>
如何获得抖音视频播放量?各位大牛支支招~ tag:www.v2ex.com,2024-11-13:/t/1089278 2024-11-13T09:31:01Z 2024-11-19T15:30:11Z ruobingm member/ruobingm 想问下各位技术大咖,如何获得抖音播放量? 首先,我通过官方通道,h5 分享后获取 item_id,然后调用抖音开放平台的# 查询特定视频的视频数据接口。 这里第一个坑,就是此接口需要通过 PC 扫码获得经营权限作用域,才可以调用。如果是 js 授权,或者 web 授权用 h5 页面授权,都不能拿到带 bind 的作用域。所以只能放弃这个路径。 然后就换了别一个,抖音开放平台数据开放服务,视频数据-“获取视频基础数据” 这个接口,可以获得到播放量,点赞数数据。原本挺好的,就这样结束。 然而,11 月 5 号,把 h5 分享到抖音能力 回收了。 突然回收,我只能做成手动不发,不分享了。但是这样的失去了获得视频 item_id 的途径。所以上面视频数据-“获取视频基础数据” 这个接口废了。。(还有其他途径,1 月份回收了,1000 粉丝以下的数据不返回,接抖音开放平台,心真的很累,说回收就回收~。) 然后我再去通过第三方,tikhub,调用了接口能获得,但是不知道为什么,在本地调用可以,到服务器就不行。服务器调用 20 多分钟就成功 1 2 次。问了那边客服,说也有腾讯云、阿里云服务器的客户出现这样的问题,让买台美国的服务器。。。。我不可能买美国的,我没这个预算,。。 所以又断掉了。。各位大神有没啥渠道能获得指定视频播放等数据,付费的都 ok ,别太贵的。。

]]>
如何优雅地切换 composer 镜像 tag:www.v2ex.com,2024-11-04:/t/1086502 2024-11-04T07:55:26Z 2024-11-04T11:07:39Z yanwushu7 member/yanwushu7 总所周知,使用 composer 的时候,切换镜像是一个刚需。但是操作频率说高不高,说低也不低,往往需要切换镜像的时候偏偏记不住命令。这时,我都会到网上搜索切换镜像的命令,以及有哪些镜像站点可用。

在 Xserver 中优雅地实现了这个功能。只需要鼠标点击一下即可快速切换镜像,即时生效。

Xserver 内置了阿里云、华为云、腾讯云和默认镜像,你可以在这些镜像之间随意快速切换。

xserver

]]>
与银行对接 sm4 国密算法 tag:www.v2ex.com,2024-10-31:/t/1085268 2024-10-31T03:51:14Z 2024-10-31T11:59:45Z cbasil member/cbasil php 相关国密算法的教程很少,找了好久才找到 github 上的包[https://github.com/lizhichao/sm]( https://github.com/lizhichao/sm)
配置好后,一运行就报错秘钥长度为 16 位。跟对方沟通后才知道他们给的是 16 进制的 32 位的 key,在 php 中需要用 hex2bin 转成 16 位。
如果对方给的加密模式是 sm4-cbc,还需要配置 iv 。默认 iv 用 hex2bin('00000000000000000000000000000000')生成。不然解密后的字符串前后会有乱码。填充方法一般常用 pkcs5 和 pkcs7 。这二种填充方式概念上没有什么区别,只是 pkcs5 在 blockSize 上固定为 8 bytes,即数据始终会被切割成 8 个字节的数据块,然后计算需要填充的长度.
加密后的字符编码也有 hex 和 base64 区分。

如果 openssl 版本大于 1.1.1 ,就可以用 openssl_decrypt($data, "sm4", $key, $optiOns=OPENSSL_RAW_DATA,$iv)来解密。 ]]>
Laravel 二手项目,语言切换问题,求解 tag:www.v2ex.com,2024-10-28:/t/1084412 2024-10-28T12:41:30Z 2024-10-28T17:00:08Z Yesr00 member/Yesr00 RT,创建了一个 SetLang 中间件, 代码如下:

if($request->input('lang')){ app()->setLocale($request->input('lang')); }

return $next($request);

首次设置生效,切换页面不带'lang'参的时候在控制器里用 app()->getLocale()就还是只能拿到默认语言。使用 session 也是一样。检查了中间件的顺序,应该是没什么问题,也没有其他的地方有设置语言操作。求 debug 思路

]]>
两道 PHP 题目,都是求 flag 值 tag:www.v2ex.com,2024-10-18:/t/1081563 2024-10-18T08:36:16Z 2024-10-18T12:00:08Z yxzblue member/yxzblue 1 、http://106.15.186.69:8061/

2 、http://106.15.186.69:8097/

]]>
帮忙推荐一个开源论坛源码? tag:www.v2ex.com,2024-09-21:/t/1074541 2024-09-21T01:28:13Z 2024-10-19T21:31:31Z RunningRabbit member/RunningRabbit 最近打算搭建一个论坛,功能可以简单点,界面差不多的论坛类源码帮忙推荐下,谢谢

]]>
Laravel 完成了 A 轮融资🎉 tag:www.v2ex.com,2024-09-05:/t/1070582 2024-09-05T15:02:27Z 2024-09-05T07:02:27Z akagishigeru member/akagishigeru @Taylor

I'm excited to announce that Laravel has raised a $57M Series A in partnership with Accel. I believe that Laravel is the most productive way to build full-stack web applications, and Laravel Cloud will be the platform for shipping those applications that this community deserves. 

首轮融资 5700 万美金。

可以用上免费的 Laravel Cloud 产品咯

]]>
PHP 虽然没落了,但是 PHP 的东西是真的好用 tag:www.v2ex.com,2024-08-30:/t/1069110 2024-08-30T09:45:00Z 2024-11-17T14:37:30Z pixcai member/pixcai 不得不说PHPLaravel框架(或者ThinkPHP)是真的好用啊,很多功能开箱即用,为什么现在的Web框架反而不这么做了呢?

比如GoGinNodeexpressPythonFlask,都是定义路由、返回JSON、模板渲染、静态文件服务这几个基础功能,想要别的需求还得自己装,自己装数据库驱动、搞注册登录、搞邮件发送什么的,更别说结合前端的VueReactTailwind CSS这些了,不会前端的搞配置都要搞半天。

反观Laravel系列,上面的功能要么自带,要么装个库运行下命令就自动全配置好了,简直不要太方便!

狠狠地被惊艳到了!

]]>
世界上最好的 serverless 平台! tag:www.v2ex.com,2024-08-27:/t/1068087 2024-08-27T03:25:31Z 2024-08-28T09:45:38Z est member/est 有这样一个 serverless 平台:

  1. 它支持超级流行的编程语言,语法简单,功能丰富,10 分钟就能学会
  2. 通过 FTP 之类的标准工具部署,而不是脑残的命令行
  3. 不用管理麻烦的服务器。基于非常成熟的 scaling 方案。也有大量网站验证过
  4. 虽然不是 docker ,但是 vhost 够用了。而且要容器化 vhost 也很容易
  5. 让人梦寐以求的“热更新”技术
  6. 超级便宜的月租
  7. 不会吊死在一颗树( vendor lock-in )上。全球遍地的厂商都支持

这么好的 serverless 是哪家?请看本贴所属节点 😆😆😆😆😆

同步发表于我的 blog

]]>
imgur 是怎么做到一个链接新窗口打开 302,但是还能作为图片显示的? tag:www.v2ex.com,2024-08-14:/t/1064947 2024-08-14T07:49:40Z 2024-08-14T18:36:17Z shendaowu member/shendaowu



点击图片会在新窗口打开,然后会 302 到网页。

图这里看到的: t/1064815

没找到合适和节点。谷歌和 AI 都不满意。 ]]>
PHP 编译器 BPC 编译 ThinkPHP8 + PHPUnit 测试 的视频来了 tag:www.v2ex.com,2024-08-13:/t/1064519 2024-08-13T01:22:19Z 2024-08-13T19:07:31Z heguangyu5 member/heguangyu5 视频有点长,1.5 倍速看也没问题.

从一个新装好的 Ubuntu 24.04 Desktop 的虚拟机开始:

  1. composer + PHP 运行项目没问题

  2. 去掉 composer 运行项目没问题

  3. PHP 跑通 PHPUnit 测试

  4. BPC 编译跑通 PHPUnit 测试

  5. PHP 环境下项目各项功能测试没问题

  6. BPC 编译运行起来项目各项功能测试没问题

[ PHP 编译器 BPC 编译 ThinkPHP8 + PHPUnit 测试] https://www.bilibili.com/video/BV1Laece6Epr/?share_source=copy_web&vd_source=fb7701afa4e3c4faaffabbe49ab11ac2

]]>
PHP 编译器 BPC 7.3 发布,成功编译 ThinkPHP8 tag:www.v2ex.com,2024-08-12:/t/1064349 2024-08-12T06:14:04Z 2024-08-12T08:47:58Z heguangyu5 member/heguangyu5 BPC 是一个 PHP Native Compiler,可以将 PHP 源码最终转译成 C 语言,然后编译成动态链接库或可执行程序.

BPC 还内置软件授权机制,最终可实现源码保护、软件授权、二进制打包三合一!

彻底解决 PHP 项目的交付问题.

How BPC Works

  1. 官网 bpc.dev
  2. 安装使用文档

写在前面:

  1. bpc 不是一个开源项目,项目历史可以翻看之前的文章和帖子.
  2. ThinkPHP8 的编译只是一个可行性验证,请勿用于生产环境.

1. 了解 ThinkPHP

之前就有网友提过能不能编译 ThinkPHP,我也翻看过几次 ThinkPHP 的代码,虽然 ThinkPHP 带有测试用例,但是一眼看去很少,不清楚能覆盖到多少功能点.

再加上我自己从没写过 ThinkPHP 的项目,对 ThinkPHP 很陌生,所以一直没有尝试编译.

由于 php 的动态性和 bpc 与 php 的高兼容特点,bpc 编译通过不代表就没问题了,如果有测试用例保障的话,通过运行测试用例可以验证编译后的二进制可执行文件是否与原来的 php 等同.

2. 迁移 OurBlog 到 ThinkPHP

之前写的一本关于 PHPUnit 的电子书《 PHPUnit in Action --- The Easy Way 》里有一个博客项目 OurBlog,虽然功能很简单,但基本的 CURD 都涉及到了,测试也非常完整.

于是就想着把 OurBlog 迁移到 ThinkPHP 试一下,由于有测试保障,这个迁移应该比较好做.

一番折腾之后,迁移成功了! 源码见: bpc-thinkphp8-ourblog

3. BPC 编译: 理清依赖

在使用 composer 创建 ThinkPHP 项目时,可以看到一个 ThinkPHP8 项目有以下依赖:

league/mime-type-detection (1.15.0) league/flysystem (2.5.0) psr/container (2.0.2) psr/http-message (1.1) psr/simple-cache (3.0.0) psr/log (3.0.0) symfony/polyfill-mbstring (v1.29.0) symfony/var-dumper (v7.1.1) topthink/think-helper (v3.1.6) topthink/think-orm (v3.0.20) topthink/framework (v8.0.3) topthink/think-filesystem (v2.0.2) topthink/think-trace (v1.6) 

进一步地,跑通 OurBlog 测试用例, 只需要搞定 3 个依赖就可以了:

  1. psr/simple-cache (3.0.0)
  2. topthink/think-helper (v3.1.6)
  3. topthink/think-orm (v3.0.20)

最后,ourblog 的前端界面能正常运行,不需要搞定所有依赖,只需要搞定下边 4 个就行了:

  1. psr/container (2.0.2)
  2. psr/http-message (1.1)
  3. psr/log (3.0.0)
  4. topthink/framework (v8.0.3)

由于 topthink/framework 和 think-orm 里都包含了 think\Facadethink\Exception , 需要把 think-orm/stubs 独立出来, 再加上 ourblog 项目本身,一共 9 个 repo, 见这里.

4. BPC 编译: 调整代码

要想一行代码不动就能编译成功,几乎是不可能的.

代码调整主要集中在 3 个方面:

  1. 语法: bpc 不支持的语法可以通过 phptobpc 做转换, 转换也不支持的,就需要手动调整代码了.
  2. 判断 php 代码文件是否存在: bpc 编译后都是二进制了,不能使用 is_file/is_dir/file_exists/glob 来判断,要换用 bpc 自己的专有函数.
  3. Reflection: bpc 不支持 Reflection,使用 Reflection 实现的功能要调整成 bpc 的方式.

代码调整的细节可以查看每个 repo 的 commit 历史.

5. 运行

  1. 创建数据库
  2. 运行 tp8-ourblog-althttpd-ubuntu-24.04-amd64

详见: bpc-thinkphp8-ourblog release v0.1

后边可以出个视频来演示一下整个编译运行的过程.

]]>
lumen 框架是不是不更新了, laravel11 都出来这么久了 tag:www.v2ex.com,2024-08-08:/t/1063401 2024-08-08T02:08:12Z 2024-08-24T21:29:49Z fengshils member/fengshils Dux Next 中后台管理系统正式版发布啦 tag:www.v2ex.com,2024-08-06:/t/1062922 2024-08-06T06:23:20Z 2024-08-06T23:05:48Z 349865361 member/349865361 先来个介绍

Dux Next 是一款简单、易用、易开发、独立部署的应用式管理系统,该系统采用各类成熟开源的三方库进行集成封装,免去后续维护的大量工作,自带开箱即用的 CMS 模块,适合长期开发和维护。配合不同的应用可以很轻松的实现您想要的站点,诸如公司网站、博客、CRM 、ERP 、商城等等。

系统组成

后端使用 SlimPHP 框架作为基础,同时整合了 Eloquent ORM 作为主要的数据驱动。同时还集成了各大 Psr 规范化的主流组件,例如 PSR-7 、PSR-11 、PSR-15 等,以确保框架具有高度的可扩展性和互操作性,该封装框架名为 Duxlite 。

前端使用 Refine 无头框架与 TDesign 组件库进行结合,快速开发美观优雅的操作界面。同时提供丰富的 Api 接口,可轻松将数据分享给三方或前台业务,该封装框架名为 Duxrefine 。

目标用户

各类 php 和全栈开发者,开箱即用快速上线项目

授权协议

MIT

仓库地址+开发文档

https://github.com/duxweb/duxcms 麻烦给个 star

https://next.dux.cn/

]]>
m1 brew 安装的 PHP @7.4 使用 pgsql 提示 SIGTRAP 错误 tag:www.v2ex.com,2024-08-06:/t/1062846 2024-08-06T02:56:11Z 2024-08-08T14:04:37Z ytvertigo0927 member/ytvertigo0927 需要适配pgsqltap用的是shivammathur/php/php@7.4 php -m 包含了基本的扩展,pdo_pgsqlpgsql扩展直接编译进了内核

➜ Formula git:(master) php -m [PHP Modules] bcmath bz2 calendar Core ctype curl date dba dom exif FFI fileinfo filter ftp gd gettext gmp hash iconv intl json ldap libxml mbstring mysqli mysqlnd odbc openssl pcntl pcre PDO pdo_dblib pdo_mysql PDO_ODBC pdo_pgsql pdo_sqlite pgsql Phar phpdbg_webhelper posix pspell readline Reflection session shmop SimpleXML soap sockets sodium SPL sqlite3 standard sysvmsg sysvsem sysvshm tidy tokenizer xml xmlreader xmlrpc xmlwriter xsl Zend OPcache zip zlib [Zend Modules] Zend OPcache 

但是new PDO()后直接提示

WARNING: [pool www] child 69580 exited with code 124 after 795.206755 seconds from start 

有人遇到过吗

]]>
有什么 PHP 分类信息网站管理源码? tag:www.v2ex.com,2024-08-03:/t/1062219 2024-08-03T05:18:17Z 2024-08-11T10:40:42Z MuskLee member/MuskLee
1 、发布企业数据库
2 、每个企业下面可以发布产品库

企业和产品都可以自定义字段,比如企业的地区,行业等,产品的各种参数。

有后台就行,前端展示可以自己做。主要不想做后台。

感谢。 ]]>
gpt-4o-mini 回答的答案和自己本机运行的结果不一致,应该相信谁? tag:www.v2ex.com,2024-07-31:/t/1061421 2024-07-31T03:28:05Z 2024-08-01T00:02:47Z frozenway member/frozenway 在 PHP 中,strpos() 函数的第一个参数是要搜索的字符串(即“haystack”),第二个参数是要查找的子字符串(即“needle”)。根据 PHP 的官方文档,strpos() 函数的第一个参数可以是空字符串。

行为说明 当第一个参数( haystack )为空字符串时: strpos() 函数会返回 0 ,表示子字符串( needle )在空字符串的起始位置找到(位置为 0 )。这是因为在 PHP 中,空字符串的起始位置被视为 0 。 示例:

$haystack = ""; $needle = "a"; $position = strpos($haystack, $needle); var_dump($position); // 输出 int(0) 

我在我本地运行得到的结果确是:

$address = ""; $word = 'a'; // $rs = strpos($address, $word); var_dump($rs); //输出 bool(false) 

这是 PHP 版本的问题还是 gpt 回答错了?

]]>
phpMyAdmin 导出 csv 性能为什么感觉强于 PHP 手写导出 csv tag:www.v2ex.com,2024-07-31:/t/1061394 2024-07-31T02:17:14Z 2024-07-31T03:22:25Z zero3412 member/zero3412 而使用如框架 thinkphp 导出相同数据时,就必须要使用分页或其它方法,否者会引起超时或内存不足等乱七八糟的问题;
如果使用原生 PHP 会比框架要好些,但依然没有 phpMyAdmin 那么丝滑。


GPT 的回复
在比较 phpMyAdmin 导出 CSV 的性能与用 PHP 手写导出 CSV 时,以下几点可能解释了为什么 phpMyAdmin 的性能更好:

优化和效率:
phpMyAdmin 是一个成熟的工具,专门设计用于与 MySQL 数据库交互。它在处理大数据集时进行了很多优化,使得导出操作更高效。
手写的 PHP 脚本可能没有进行类似的优化,尤其是如果没有充分考虑内存管理和数据库查询的效率。

使用 LOAD DATA:
在导出 CSV 文件时,phpMyAdmin 可以使用 MySQL 的 LOAD DATA 功能,这比 PHP 手写代码更高效

数据库查询优化:
phpMyAdmin 在执行查询时可能使用了一些最佳实践,例如分页查询以避免内存溢出。
手写的 PHP 脚本如果没有适当的查询优化,可能会导致性能瓶颈,尤其是在处理大数据集时。

内存管理:
phpMyAdmin 可能使用了流式处理( streaming )技术,即逐行读取数据并写入 CSV 文件,从而降低内存占用。
如果手写的 PHP 脚本一次性读取大量数据并存储在内存中,再进行写入操作,内存消耗会非常高,导致性能下降。

文件处理:
phpMyAdmin 可能使用了更高效的文件写入方式,例如使用内置的函数进行批量写入。
手写的 PHP 脚本如果使用的是逐行写入且没有进行缓冲操作,会导致 I/O 操作频繁,从而影响性能。

错误处理和重试机制:
phpMyAdmin 内置了错误处理和重试机制,可以在出现错误时有效地处理和恢复,从而保证导出过程的顺利进行。
手写的 PHP 脚本如果没有完善的错误处理机制,在出现错误时可能会中断导出过程,导致性能不稳定。
缓存机制:

phpMyAdmin 可能利用了缓存机制来提高数据读取和写入的效率。
手写的 PHP 脚本如果没有使用缓存,数据的读写效率可能会较低。
总结来说,phpMyAdmin 在导出 CSV 的过程中,利用了很多性能优化技术和最佳实践,使得其导出性能优于一般的手写 PHP 脚本。如果希望提高手写 PHP 脚本的导出性能,可以参考 phpMyAdmin 的一些优化策略和技术。 ]]>
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86