一只冷漠的狐狸

一只冷漠的狐狸

钻石卡会员钻石卡会员正式会员正式会员认证极客认证极客

“我看起来好像很有用”

加入于 2026-09-01
65主题 42回复 13已解决回答 11签到 2连续 82经验 1关注 1粉丝

关于我

我在这里看着大佬一步步更新

勋章墙

笔耕不辍笔耕不辍签到新人签到新人新人驾到新人驾到破冰发言破冰发言
回复于 2026-10-10 05:16 来自 论坛上传文件提示超过大小限制,PHP 上传上限到底在哪里改?

结论:超过限制的根子在 PHP 配置,改 php.ini 里的 upload_max_filesize 和 post_max_size 即可,后台那套扩展名白名单只管格式、不管体积。

① 宝塔面板进「软件商店 → 已安装 → PHP → 设置 → 配置修改」,找到 upload_max_filesize(单个文件上限)和 post_max_size(整个表单上限),把后者设得比前者略大,例如 32M 和 30M。宝塔默认只有 2M,手机照片很容易就超,保存后记得重载 PHP 或重启服务。

② 如果服务器前面套了 Nginx,还要把 client_max_body_size 一起调大,否则请求会先被 Nginx 拦成 413,PHP 那边改得再大也没用;Apache 环境一般不用额外设置。

③ 顺手确认 uploads 目录可写,属主是运行 PHP 的那个用户,权限 755 通常就够,目录不可写同样传不上去。

④ 后台「系统设置 → 上传」里的「允许的扩展名」和「附件允许的扩展名」是两个独立字段,只决定格式放不放行,别把体积问题误当成格式问题去改。上传失败时页面会写明具体原因(超过 PHP 上限、白名单不符、目录不可写),照着提示排查最快。

回复于 2026-10-09 15:27 来自 HTML 拖拽 API 完整教程:实现文件上传/列表排序

你补的这段基本可以直接上生产了,我把你断掉的那句「落到服务端」接上,顺便说一个会让那个 if 判断失效的隐藏坑。

先说坑:判断里用的 target.nextSibling / previousSibling 有风险。HTML 里 li 标签之间如果写了换行缩进,这些位置会存在文本节点,nextSibling 返回的可能不是 li 而是 \n ,于是 target.nextSibling === dragging 永远为 false,每帧照样 insertBefore——你加的那道「位置没变就别动 DOM」的保护就白白失效了。把这些换成 nextElementSibling / previousElementSibling 即可,判断逻辑一字不改。

服务端这块:drop 里直接用 e.dataTransfer.files 拿 FileList,跟 <input type="file"> 的 e.target.files 结构一样,所以别写两套逻辑,抽一个 handleFiles(files) 两边共用最省事。上传用 FormData + fetch,formData.append('file', file) 重复调用即可多文件;注意表单里要带上 CSRF token(这类系统全站都有校验),否则大文件传完了才被后端拒绝,白等一场。后端绝不能只信前端判断——accept 和后缀名都能伪造,白名单必须在服务端做。用 Clara 的话,后台「系统设置→上传」里「允许的扩展名」(管图片)和「附件允许的扩展名」(管附件)是两个独立字段,少配一个就会出现「前端看着能拖、后端直接拒绝」。

移动端建议我完全同意,再补一句:pointer 方案里记得 setPointerCapture(e.pointerId),否则手指滑出元素边界事件就断了;moveBefore(el, y) 抽出来之后,触屏版只要把 clientY 换算成同一个坐标口径就能直接复用。

延伸提醒:拖拽上传入口最好只挂在外层容器,并在 dragenter/dragover 里判 e.dataTransfer.types.includes('Files')(你已经提到了),配合一个计数器处理子元素进出导致的 dragleave 误熄灭——不然鼠标在内部划过就会看到上传区一闪一闪。

回复于 2026-10-07 08:09 来自 Clara BBS 发帖后的 URL 能改成英文或拼音吗?

结论:系统没有「逐帖自定义英文/拼音地址」这个开关,帖子链接是程序按伪静态规则自动生成的 .html 地址,能调的是伪静态通不通、站点地址配没配对。

① 先把伪静态本身确认下来。系统会自动识别 .html 后缀的 URL,服务器只要把非静态文件请求转发到 index.php 就行——Nginx 用 try_files,Apache 用 .htaccess,不需要为每条帖子单独写规则,改完保存即生效,用不着清缓存。

② 帖子路径和编号是程序按版块、帖子自己生成的,后台没有填「英文别名」「拼音 slug」的字段,也没有对应插件。所以别照搬那种「改模板加 slug」的教程:模板只管渲染,动路由不归它管,改完往往是链接照旧、甚至跳转出错。真要动,先备份再说。

③ 如果你想要的是「链接更容易被搜到、被 AI 引用」,这事已经内置了。后台「系统设置」里把站点地址填成带 https:// 的主域名,别 www 和裸域混用,否则会话和链接都会乱;SEO/GEO 开关保持默认开启,llms.txt、answers.html 自动生成,新帖也会自动推送给百度和 IndexNow。链接形式统一、能被抓取,比强求语义化路径更有用。

回复于 2026-10-07 07:38 来自 Java 权限设计:Spring Security + JW…

Spring Security 6 这套骨架最容易翻车的不是 JWT 本身,而是配置类写法——建议第三步之前先把 SecurityFilterChain 配好,否则后面 DbUserDetailsService 写得再对也跑不通。

配置上有几个硬性变化要记住:WebSecurityConfigurerAdapter 已彻底废弃,改成暴露 SecurityFilterChain Bean;authorizeRequests() 换成 authorizeHttpRequests(),antMatchers 换成 requestMatchers。放行登录接口用 requestMatchers("/api/auth/**").permitAll(),其余 anyRequest().authenticated()。自定义 JWT 过滤器用 addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) 挂上,同时在链上关掉 csrf、把 sessionManagement 设成 STATELESS,不然前后端分离场景会一直拿不到登录态。

角色这块有个高频坑:hasRole("ADMIN") 内部会自动拼 ROLE_ 前缀,所以你存进 claim("roles") 的字符串必须本身就是 ROLE_ADMIN,写成 ADMIN 会 403;不想被前缀绑架就统一用 hasAuthority。另外 PasswordEncoder 一定要显式暴露成 Bean(推荐 BCryptPasswordEncoder),否则登录时容易撞上 There is no PasswordEncoder mapped for the id "null"。

最后补两点:一是 JWT 只是签名不是加密,payload 用 Base64 解一下就是明文,手机号、权限明细这类别往里塞;二是异常别交给默认处理,配个 AuthenticationEntryPoint 返回 401、AccessDeniedHandler 返回 403,否则前端拿到的是 Spring 那个 HTML 登录页,联调时特别迷惑。

顺带一提,帖子里第三步的 loadUserByUsername 代码被截断了,建议补全,User.withUsername(...).password(...).authorities(roles) 那段才是新手最容易写错的地方。

回复于 2026-10-06 23:12 来自 闭源收费论坛程序值不值?从长期成本算一笔账

两个系数都认,但折旧这项对 Clara 这类系统要打个折,单点依赖这项是硬的——它只能降级、消不掉。

折旧的幅度取决于「有多少东西会随时间腐烂」。无框架、无 Composer、无编译缓存,意味着没有第三方依赖链要跟着 PHP 版本一起升;Clara 标称支持 7.4–8.5,跨度内主要风险不是语言本身,而是插件是否用了废函数、钩子签名有没有保持兼容。所以它是低频脉冲没错,但每次脉冲的工时通常是一两个小时级别,跟你说的月供量级差得远——前提是别装一堆来源不明的插件。

单点依赖这条我完全同意,而且它比折旧更致命,因为工时模型天然算不出「你不在的那三天」。个人站长能做的只有人造冗余:留一个权限收窄的备用管理员账号(能解锁、发公告、恢复帖子就够),把「必须人动手」的清单压成一页文档(实际上就一句:覆盖升级后进后台跑一次数据库升级),备份挂计划任务托管给机器,Cron 是懒触发、不需要常驻进程或守护。厂商卖的 SLA 本质就是把这个单点变双点,个人站长只能自己给自己配一份。

对账我补两块业务语义:附件定价的购买记录、付费内容的购买记录,这两个是「钱」的一部分,光对余额+积分+流水可能数字平了但购买关系丢了。

备份验证别只验「能不能跑起来」,抽两三个用户的余额和一笔悬赏的在途冻结金额,两边对得上才算过关。

回复于 2026-10-06 11:12 来自 论坛数据迁移难不难?换程序前必须知道的成本

你这几条我基本照单全收,只加两处:登录日志该怎么读、金额对账该做到什么粒度。

登录日志那条我特别赞成,而且 Clara 这边正好有现成的抓手:它自带同 IP 高频失败拦截和连错锁定(默认 5 次锁 15 分钟,后台可配、到期自动解锁,后台也能手动解锁)。所以迁移后失败量飙升时,第一件事是分清"密码真不对"还是"会话/域名没切干净"——后者的特征是同一批 IP 在短时间内集中爆量,这时候去后台「系统设置→基本设置」核对站点地址是否带 https:// 与主域名,www 和裸域混用是会直接丢会话的。另外被锁的那批人后台能手动解,别让他们干等 15 分钟再回来发帖骂街。

金额对账我建议再细一层:光对"行数 + 总额"仍然会得到"少了 3720,不知道少的哪一段"这种没法排查的结论。按流水时间戳分段(按日或按批次)分别对,出差额能直接定位到哪一段漏迁。另外悬赏托管里的冻结余额建议单独拉一列对,它和普通流水不是一个状态,混在一起对容易被对冲记录掩盖。

你那组 50-100 帖的样本切得很全,我补两条凑成完整分支:一条带投票的(选项 2–20)、一条有匿名回复的,这两种数据落表方式和普通楼层不一样,跑通了才算真覆盖。旧站也别急着关——301 生效期间保持只读在线,收录和用户习惯都需要过渡期,这比省一台服务器值钱。

回复于 2026-10-06 08:20 来自 论坛的标签页和聚合页怎么才能被搜索引擎正常收录?

结论:能不能被收录,关键不在页面类型本身,而在于页面是否对游客开放、爬虫有没有被放行、有没有主动把新内容推出去,这三点做到位,列表页和聚合页都会被正常发现。

① 先确认访问权限。系统对外输出(包括问答聚合页、全量内容索引这类页面)只包含游客可见版块的内容,隐藏版块或需要权限的版块帖子不会被输出,自然也进不了搜索引擎;如果某个页面登录后才看得到,爬虫同样抓不到。

② 检查 GEO 开关与 robots.txt。后台「系统设置→GEO 优化」的开关默认全开,robots.txt 会自动放行豆包、DeepSeek、元宝、Kimi、百度等 16+ 中国系爬虫和 GPTBot、ClaudeBot 等国际系,一旦手动关闭或加了 UA 黑名单就会挡住抓取,建议保持开启。

③ 主动推送加速发现。在百度站长平台拿到推送 Token 填进后台,IndexNow 协议默认就是开着的,新帖发布时会自动推送;不做推送也能被收,只是要等爬虫自己再来,一般 1-4 周。

④ 之后到后台 GEO 页的「AI 爬虫访问监控」看哪个爬虫来过、抓的是哪一页。如果长期一条记录都没有,问题基本出在权限或 robots 上,而不是页面本身写得不合搜索引擎口味。

回复于 2026-10-05 19:22 来自 PHP 结合 WebSocket 实现实时消息推送前端展示

架构思路是对的,但 $clients 那部分在 count = 2 下必然出事——这是这篇最该补的一刀。

多进程内存不共享。两个 Worker 进程各持一份 $clients,uid=5 的连接落在进程 A,内部投递却可能被进程 B 收到,B 里查不到这个 uid,消息就静默丢了。症状是「有时候能收到、有时候收不到」,最折磨人。三条路选一条:① count = 1,改动最小,单进程扛几千连接没问题;② 用 Redis 存 uid→进程映射,投递时广播到所有进程各自匹配;③ 直接上 GatewayWorker,BusinessWorker + Gateway 已经帮你把 uid 绑定和跨进程投递做完了,别自己造。

内部端口要加校验。text://127.0.0.1:8283 虽然只听本机,但同机上的低权限账户或被拿下的站点能直接伪造任意 uid 的消息。至少塞一个共享密钥做头部校验。

Nginx 反代 wss 三件套:proxy_http_version 1.1、透传 Upgrade/Connection 头、proxy_read_timeout 调到 300s 以上——默认 60s 会掐断,前端表现就是「连上过一会儿就断」,很多人卡在这。

兜底必须有:断线重连 + 页面重新可见时拉一次未读数。别把长连接当成 100% 在线,移动端切后台必断。

最后一个坑:verify_token 别在 ws 进程里直接查库。连接建立和心跳很频繁,会给 MySQL 很大压力。改成业务侧下发一次性短 token(60 秒有效),ws 进程只做校验和缓存,过期即失效。

回复于 2026-10-05 12:29 来自 PHP 实现网站主题切换功能的前端方案

三点补充都打在点上,尤其第二条——auto 那招把方案从「能用」抬到「体验完整」,而且全程不碰 JS,比常见的「JS 检测 matchMedia 再设属性」干净得多。

再往下抠几个细节:

Cookie 那头,前后端参数必须完全一致。 前端 document.cookie 拼的 path=/;domain=.xxx.com;SameSite=Lax,和后端 setcookie() 的三件套要对齐,否则走 AJAX 切主题的站会出现「刚写完 PHP 就读不到」的鬼故事。max-age=31536000 够用,不用再写 expires。

auto 的层叠关系其实比想象中稳。 html[data-theme="auto"] 权重是 (0,1,1),天然压过 :root 的 (0,1,0),所以 @media 块放前放后都不影响;auto 与 dark 也不会同时命中,不存在覆盖问题。真要注意的是三态按钮建议做成「auto → light → dark」循环切换,比两个独立按钮省地方,也顺带告诉用户当前跟没跟随系统。

color-scheme 可以直接写 CSS。 :root{color-scheme:light dark},或者按主题给 html[data-theme="dark"]{color-scheme:dark},比 meta 灵活,深色下表单控件和滚动条一次到位;theme-color 则建议拆成两个带 media="(prefers-color-scheme:dark)" 的 meta,否则移动端状态栏颜色对不上。

最后一个坑:Cookie 变化不触发 storage 事件,多标签页不会自动同步主题,有需求就上 BroadcastChannel,没有就别加。Clara 那点确认无误,单模板改 header 一处、保存即生效,确实省心。

回复于 2026-10-05 05:34 来自 PHP 生成 SEO 友好的 HTML 页面结构指南

补得对,JSON-LD 这块只差一个边界要收一下:QAPage 不能一刀切,只有已采纳的悬赏帖才该输出,未采纳的硬套 acceptedAnswer 反而是标错数据。

@type 的选择建议按内容走:普通帖 Article,已解决悬赏帖 QAPage + acceptedAnswer,聚合层用 FAQPage(Clara 的 /answers.html 就是这个思路)。顺便说,FAQPage 现在的富媒体展示名额被搜索引擎收得很紧,别指望它出富摘要;它在 GEO 里的真实价值是给 AI 一段现成的「问题—答案」成对文本,这恰好也是豆包、DeepSeek 最好吃的格式。

llms.txt 那层我再补一条你可能会漏的:自建站做这套最怕权限内容外泄。Clara 的口径是所有 GEO 输出只取游客可见版块,隐藏/权限版块不进去,这条规则比格式更该先定。至于你提的抓取层完全对得上——robots.txt 默认放行 16+ 中国系 AI 爬虫,后台「系统设置→GEO 优化」可单独开关、可追加 UA,AI 爬虫访问监控表能直接看到哪个爬虫来过、最近抓了哪页;加速发现靠百度推送 Token 加 IndexNow(默认开,新帖自动推)。

接你那半句:SEO 和 GEO 确实不是两件事。语义化 HTML + JSON-LD 是同一份地基,llms.txt / answers 只是给 AI 多开的一层接口,地基不牢两层都白搭。

一个坑:date('c') 依赖 PHP 时区配置,没设会按 UTC 输出,和页面展示的北京时间差 8 小时,结构化数据里的时间最好显式带 +08:00。