最近比较忙，很久没有更新博客了，今天刚好有空，打算水一篇，就来说说刚才更新的Typecho吧。话说Typecho终于更新了正式版本1.2.0，距离上个版本1.1(17.10.30) 正式版发布已近五年时间了，真可谓有生之年系列。五年时间足以改变很多人和事，但Typecho还能保持初心一如既往的坚持下来也算不负广大用户的期待了。念念不忘，必有回响，N 年 Typecho 沉淀，现在，回应您的等待。更新了什么这个版本的开发经历了如此长的时间，以至于我无法一次性列出这么长的详细改进列表。除了修复了很多bug以外，我们重要的改进有如下几点：新的编辑器实时预览自动跟随效果，以及主题内预览功能后台界面对移动端的适配新的安装程序进入 PHP 7.2 时代，以及对 PHP 8 的更好支持对容器化的更好支持除了新功能，大家也可以发现我们的版本号规则有变化。新的版本号会采用常规的3组数字组成，比如 1.2.0 。之前是 [大版本/时间版本] 这样的形式，比如 1.1/17.10.30，代表的是在2017年10月30日发表的1.1版本。新的版本号采用常规的3组数字组成。比如1.2.0，前面两部分是大的版本号，重要更新的时候会变化，最后一位适用于微小更新，针对一些微小的bug修复更新。安装环境要求除了以前的几项以外，1.2.0版本PHP最低要求是v7.2- PHP 7.2 以上，支持PHP 8.0 - MySQL, PostgreSQL, SQLite 任意一种数据库支持，并在 PHP 中安装了相关扩展 - CURL 扩展支持 - mbstring 或 iconv 扩展支持 下载[btn href="http://typecho.org/download" type="#409eff"]官网下载 ♥️[/btn] [btn href="https://github.com/typecho/typecho/releases" type="#000000"]Github 🐙[/btn] [btn href="https://github.com/typecho/typecho/releases/latest/download/typecho.zip" type="#28a745"]直接下载（github）📥[/btn] [btn href="https://mirror.ghproxy.com/https://github.com/typecho/typecho/releases/download/v1.2.0/typecho.zip" type="#138496"]国内高速 🎯[/btn] [btn href="https://www.123pan.com/s/sKeA-9Z5mA" type="#f56c6c"]网盘下载 🐳[/btn]升级备份网站及数据库（虽说一般情况下不会有问题，但多备份还是很必要的）；进入后台，切换主题为系统默认，禁用所有插件，升级完成后再切换主题以及开启插件（非必需，但是这样会减少很多问题）；下载最新版Typecho，并上传下面的文件夹及文件覆盖旧版文件（如果是FTP上传，请将上传方式设置为二进制模式）；/admin/ /var/ /index.php /install.php登入网站后台，会检测到新版本，点击 完成升级 按钮，整个升级过程就完成了，这时你就会看到后台提示，你所使用的文件版本以及官方最新版本。（如下图）最后到这里整个Typecho 1.2.0的升级过程就记录完了，过程也比较简单，因为本博客早就升级过来，为了水这篇文章，添加截图，不得已又翻出了另外一个荒废的网站给升了个级，真是不容易啊。说点题外话，因为众所周知的原因，cdn.jsdelivr.net 的国内CDN已经被墙了，本站的图片原来大多数都托管在GIthub Repo，虽然已经切换到了 gcore.jsdelivr.net ，但是速度还是不理想，这就导致国内用户访问本站有点慢，所以今后的图片还是托管的自建的Chevereto图床。今天在上传图片的时候出现了一个很奇怪的问题，webp文件无法上传，经过一番折腾终于找到了原因，这就有了下面这篇文章。[post]2221[/post]
Joe主题更新到5.0.0版本后，因为属于重构版本，所以很多功能没有加上，需要频繁更新，但是每次更新都需要下载，然后删除老版本，在上传新版本，今天群里有个人分享的自动更新教程写的很好，于是我把补充的详细点[jline]START[/jline]第一步，克隆主题1、首先进入博客的 themes 文件夹下2、点击 终端 按钮，出现一个黑色的窗口3、 在这个窗口内输入以下指令并回车git clone https://github.com/HaoOuBa/Joe.git出现下图的样子，表示成功4、刷新当前页面，会发现多出一个叫 Joe 的目录第二步，设置自动更新主题1、进入宝塔 计划任务 页面2、任务类型选择 Shell 脚本3、任务名称，可以随便写一个，例如我写的是：Joe主题更新4、执行周期，就是多久更新一次，这个可以随便写，例如我设置的是每30分钟检测一次更新5、脚本内容，填写如下，注意需要将网站目录替换成你的#!/bin/sh cd /www/wwwroot/网站目录/usr/themes/Joe git pull完整的设置内容如下第四步，判断是否正常1、上面步骤都完成后，点击这里的 执行2、然后点击 执行 右侧的 日志 按钮，如果内容显示如下，则代表没有任何问题[jline]END[/jline]https://78.al/post/52.html
Typecho 第一款支持黑暗模式的后台主题插件！
SimpleAdmin 是一款即插即用的typecho后台美化插件.gogobody修改自小王先森 的后台插件，登录界面修改自泽泽站长（qqdie）的登录插件。[scode type="error"]上传后插件目录名修改为SimpleAdmin，否则启用不了上传后插件目录名修改为SimpleAdmin，否则启用不了上传后插件目录名修改为SimpleAdmin，否则启用不了[/scode]插件项目var needGithubWidget=1;.github-box {max-width: 100%;margin: 0 10px;} .github-box .github-box-download .download {top: 8px;} .github-box a {margin-top: -1px;margin-left: 2px;margin-right: 2px;} .github-box .github-box-title h3 {background: url([binary]) 5px center no-repeat;}注意本插件推荐 php 版本 7+ 。部分用户启用插件后出现白屏，请不要惊慌，正常操作，只需要等待60秒左右。因为PHP 5.5+版本以上的可能启用了PHP自带的opcache来加速脚本。但是如果opcache.revalidate_freq参数越大，服务器单位时间能接收的请求越多，但是加载代码的频率越低，会造成代码加载不及时的问题。您可以调整php.ini中的opcache.revalidate_freq为 0 来刷新脚本。下载[btn href="https://github.com/gogobody/SimpleAdmin/archive/refs/tags/1.1.4.zip" type="#28a745"]SimpleAdmin-1.1.4下载[/btn]特色插件，即插即用安全，不会破坏您的原有文件轻量级，几乎纯js,css修改支持 gogobody 原创的黑暗模式手机，pc 自适应界面绝对简洁！预览PC样式手机样式转自：即刻学术
一、伪静态规则整理（Apache + NGINX）1、Apache 环境（.htaccess）<IfModule mod_rewrite.c> RewriteEngine On # 下面是在根目录，文件夹要修改路径，如 /oldtang/ RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php/$1 [L]2、NGINX 环境location / { index index.html index.php; if (-f $request_filename/index.html) { rewrite (.*) $1/index.html break; } if (-f $request_filename/index.php) { rewrite (.*) $1/index.php; } if (!-f $request_filename) { rewrite (.*) /index.php; } }3、nginx二级目录location /blog/ { if (-f $request_filename/index.html){ rewrite (.*) $1/index.html break; } if (-f $request_filename/index.php){ rewrite (.*) $1/index.php last; } if (!-f $request_filename){ rewrite (.*) /blog/index.php last; } }注意blog就是您自己的二级目录，请根据实际情况调整。LAMP 建站教程，可以参考：《使用 LAMP 一键包部署 Linux 建站环境》。如果需要配置 SSL，并做强制 https 跳转，可以参考《LAMP 环境下安装配置 SSL 证书并自动跳转到 HTTPS》。二、开启gzip压缩，加速网站访问Gzip是一种常用的HTML压缩技术，通常情况下，Gzip开启后会将输出到用户浏览器的数据进行压缩的处理，这样就会减小通过网络传输的数据量，提高浏览的速度。Typecho的gzip压缩开启Typecho的gzip功能很简单，是和wordpress一样的，只要在根目录下的index.php文件里面加上下面这一句就可以了：/*添加Gzip*/ ob_start('ob_gzhandler');注意，是整个网站根目下的index.php文件，不是在主题目录下的。上面这句话建议加在最上面三、升级全站https数据库批量替换网址/内容内容UPDATE `typecho_contents` SET `text` = REPLACE(`text`,'旧域名地址','新域名地址');自定义UPDATE `typecho_fields` SET `str_value` = REPLACE(`str_value`,'旧域名地址','新域名地址');评论UPDATE `typecho_comments` SET `text` = REPLACE(`text`,'http://','https://'); UPDATE `typecho_comments` SET `url` = REPLACE(`url`,'http://','https://');四、TYPECHO支持emoji最近写文章的时候用到了emoji，发现报错：Database Query Error解决办法1、进入数据库，直接运行下列语句：alter table typecho_comments convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_contents convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_fields convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_metas convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_options convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_relationships convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_users convert to character set utf8mb4 collate utf8mb4_general_ci;2、修改数据库的配置文件网站根目录数据库配置文件config.inc.php，大约在60行/** 定义数据库参数 */ $db = new Typecho_Db('Pdo_Mysql', 'typecho_'); $db->addServer(array ( ... 'charset' => 'utf8mb4', // 将原来的utf8修改为 utf8mb4 ... ), Typecho_Db::READ | Typecho_Db::WRITE); Typecho_Db::set($db);五、模板添加备份恢复功能代码在themeConfig($form)函数里添加$db = Typecho_Db::get(); $sjdq=$db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:Yodu')); $ysj = $sjdq['value']; if(isset($_POST['type'])) { if($_POST["type"]=="备份模板数据"){ if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:Yodubf'))){ $update = $db->update('table.options')->rows(array('value'=>$ysj))->where('name = ?', 'theme:Yodubf'); $updateRows= $db->query($update); echo ' 备份已更新，请等待自动刷新！如果等不到请点击'; ?> <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里 <?php }else{ if($ysj){ $insert = $db->insert('table.options') ->rows(array('name' => 'theme:Yodubf','user' => '0','value' => $ysj)); $insertId = $db->query($insert); echo ' 备份完成，请等待自动刷新！如果等不到请点击'; ?> <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里 <?php } } } if($_POST["type"]=="还原模板数据"){ if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:Yodubf'))){ $sjdub=$db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:Yodubf')); $bsj = $sjdub['value']; $update = $db->update('table.options')->rows(array('value'=>$bsj))->where('name = ?', 'theme:Yodu'); $updateRows= $db->query($update); echo ' 检测到模板备份数据，恢复完成，请等待自动刷新！如果等不到请点击'; ?> <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里 <?php }else{ echo ' 没有模板备份数据，恢复不了哦！ '; } } if($_POST["type"]=="删除备份数据"){ if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:Yodubf'))){ $delete = $db->delete('table.options')->where ('name = ?', 'theme:Yodubf'); $deletedRows = $db->query($delete); echo ' 删除成功，请等待自动刷新，如果等不到请点击'; ?> <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里 <?php }else{ echo ' 不用删了！备份不存在！！！ '; } } } echo ' ';然后将里面出现的所有“yodu”改成你的模板目录的名字，如果拿不准就去数据库里看看模板的值名字。备份当用户点击备份时，先判断是否已经存在备份，如果不存在就插入一条新的数据，数据name为yodubf，value为模板原本的数据。此时就存在了一条备份数据。如果再次点击备份按钮会发生什么呢？会触发更新数据的语句，就是读取模板的设置数据，然后将备份的模板数据更新。还原当用户点击还原按钮时，会判断是否存在备份，如果不存在就发出提示说不存在数据无法恢复；如果存在，就会进行一个反向的更新操作，将备份的数据更新到模板默认设置数据。这个操作完成后会触发个小问题，比较影响体验的。就是在点击还原按钮时网页是先刷新后执行php还原语句的，也就是说还原完成后，你看到的模板设置页面数据并没有还原，但是实际数据库里面已经还原好了的，这一点很影响体验。于是乎，我鸡贼的弄了个js自动刷新语句，并发出提示文字，这样一下子就友好多了，注意文章中代码方面我并未给出css样式，所以美观度上需要自行优化。删除删除就简单了，判断是否存在备份，不存在就告诉用户不用删了，你压根就没有备份数据，如果有备份就执行删除语句，发出提示。一些没用的说明1，其实这东西应该可以写成懒人版的，模板名字什么的用php获取下，就不用我这样写死了，但是当时我处于试一试的心态写的，所以就能简单就简单了，现在又懒得弄了，要不是为了水文，这个我都懒得贴出来。2，别看文章中代码这么乱，条例就不清晰，其实我当时找了张纸写的逻辑然后才按照顺序一步一步的写的，也测试了很多回。3，最开始想写自动还原模板数据来着，就是检测到模板启用就自动还原曾经的备份数据，然而当时想不通如果去判断模板启用。4，当你想将本文章代码投入使用时，最好再测试博客进行测试，以免伤害你的数据库，同时建议测试时打开数据库管理页面，观看数据库对应表的变化六、为Typecho添加webp解析Typecho 原生不支持解析 Webp 图片，在附件插入 webp 文件会被当做文件解析，因此需要魔改 typecho。废话不多说，上教程。在 var/Widget/Abstract/Contents.php 中的 686 行左右：将这行代码$value['attachment']->isImage = in_array($content['type'], array('jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp'));替换为$value['attachment']->isImage = in_array($content['type'], array('jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp', 'webp'));再到 var/Typecho/Common.php 的第 1193 行左右添加如下代码'webp' => 'image/webp',最后到 Typecho 后台 -> 设置 -> 基本 -> 允许上传的文件类型 -> 添加 webp 即可完成解析。七、其他获取某个分类下的文章列表$category = $this->widget('Widget_Archive@category', 'pageSize=6&type=category', 'mid=1'); while($category->next()){ // todo here ... ... } mid表示分类id，type指定获取分类文章获取某关键词的搜索结果$search = $this->widget('Widget_Archive@search', 'pageSize=10&type=search', 'keywords=typecho'); while($search->next()){ // todo here ... ... } type指定搜索类型，keywords指定搜索关键词获取某个tag的文章列表$tags = $this->widget('Widget_Archive@tag', 'pageSize=10&type=tag', 'mid=2'); //或者：$tags = $this->widget('Widget_Archive@tag', 'pageSize=10&type=tag', 'slug=tag_name'); while($tags->next()){ // todo here ... ... } type指定tag类型，mid表示tag的id，slug表示tag的缩写名获取某篇特定的文章$post = $this->widget('Widget_Archive@post', 'type=post', 'cid=1'); $post->title(); ... ... type指定post进而获取文章，cid指定文章id站点名称<?php $this->options->title() ?>站点网址<?php $this->options ->siteUrl(); ?>站点说明<?php $this->options->description() ?>文章/页面的作者<?php $this->author(); ?>作者头像< ?php $this->author->gravatar('40') ?>上下篇调用代码<?php $this->thePrev(); ?> <?php $this->theNext(); ?>判断是否为首页，输出相关内容<?php if ($this->is('index')): ?> //是首页输出内容 <?php else: ?> //不是首页输出内容 <?php endif; ?> 文章/页面评论数目 <?php $this->commentsNum('No Comments', '1 Comment' , '%d Comments'); ?>截取文章内容显示摘要（350是字符数）<?php $this->excerpt(350, '.. .'); ?>调用自定义字段<?php $this->fields->fieldName ?>RSS地址<?php $this->options->feedUrl(); ?>获取最新评论列表<?php $this->widget('Widget_Comments_Recent')->to($comments); ?> <?php while($comments->next()): ?>[{date}](https://www.dpaoz.com/permalink(); ?>">author(false); ?>: excerpt(50, '...'); ?> 分类名称（无链接）category(',', false); ?>获取文章时间归档 widget('Widget_Contents_Post_Date', 'type=month&format=F Y') ->parse(''); ?>获取标签集合<?php $this->widget('Widget_Metas_Tag_Cloud', 'ignoreZeroCount=1&limit=28')->to($tags); ?> <?php while($tags->next()): ?> <a href="<?php $tags->permalink(); ?>" class="size-<?php $tags->split(5, 10, 20, 30); ?>"><?php $tags->name(); ?> <?php endwhile; ?>登陆与未登录用户展示不同内容<?php if($this->user->hasLogin()): ?> //登陆可见 <?php else: ?> //未登录和登陆均可见 <?php endif; ?>自动调用img字段内容，如果没有，去文章搜索第1个图片。<?php if (array_key_exists('img',unserialize($this->___fields()))): ?><?php $this->fields->img(); ?><?php else: ?><?php preg_match_all("/\<img.*?src\=(\'|\")(.*?)(\'|\")[^>]*>/i", $this->content, $matches); $imgCount = count($matches[0]); if($imgCount >= 1){ $img = $matches[2][0]; echo << <?php endif; ?>文章内容替换七牛网址<?php echo $str = str_replace("your.com/usr/uploads","your.qiniu.com/usr/uploads",$this->content); ?>文章字数统计在functions.php中写入代码：function art_count ($cid){ $db=Typecho_Db::get (); $rs=$db->fetchRow ($db->select ('table.contents.text')->from ('table.contents')->where ('table.contents.cid=?',$cid)->order ('table.contents.cid',Typecho_Db::SORT_ASC)->limit (1)); echo mb_strlen($rs['text'], 'UTF-8'); }在模板中调用：<?php echo art_count($this->cid); ?>自动调用第1个文章图片<?php preg_match_all("/\<img.*?src\=(\'|\")(.*?)(\'|\")[^>]*>/i", $this->content, $matches); $imgCount = count($matches[0]); if($imgCount >= 1){ $img = $matches[2][0]; echo << title}"> title}"> Html; } ?>边栏不显示博主评论<?php $this->widget('Widget_Comments_Recent','ignoreAuthor=true')->to($comments); ?>前台登录表单<form action="<?php $this->options->loginAction()?>" method="post" name="login" rold="form"> <input type="hidden" name="referer" value="<?php $this->options->siteUrl(); ?>"> 登录 ......
站点动态标题<?php $this->archiveTitle(array( 'category'=>_t('分类 %s 下的文章'), 'search'=>_t('包含关键字 %s 的文章'), 'tag' =>_t('标签 %s 下的文章'), 'author'=>_t('%s 的主页') ), '', ' - '); ?>站点地址，名称与描述<?php $this->options->siteUrl(); ?>//站点地址 <?php $this->options->title(); ?>//名称 <?php $this->options->description() ?>//描述index.php文章循环输出<?php if ($this->have()): ?>//判断文章存在与否 <?php while($this->next()): ?>//开始循环 <a href="<?php $this->permalink() ?>"><?php $this->title() ?>//文章标题和超链接 <a href="<?php $this->author->permalink(); ?>"><?php $this->author(); ?>//作者名称和超链接 <?php $this->date('F j, Y'); ?>//文章发布时间 <?php $this->category(','); ?>//文章分类 <?php $this->commentsNum('%d Comments'); ?>//评论数量 <?php $this->content('Continue Reading...'); ?>//阅读全文more语法截取缩略内容（可改为<?php $this->excerpt(140,'....'); ?>自动截取前140个字符，根据需要也可以改成 <?php $this->summary(); ?新版功能，自动输出内容中第一个块级元素中的内容>） <?php endwhile; ?>//循环结束 <?php else: ?>暂无与之相关文章<?php endif; ?>//判断结束翻页代码<?php $this->pageNav('上一页', '下一页', '5', '……'); ?>//显示多个页码的 <?php $this->pageLink('下一页','next'); ?> <?php $this->pageLink('上一页'); ?>//只显示上一页下一页页码显示当前页码：<?php if($this->_currentPage>1) echo $this->_currentPage; else echo 1;?> 总页码：<?php echo ceil($this->getTotal() / $this->parameter->pageSize); ?>文章全文显示<?php $this->content(); ?>登陆判断<?php if($this->user->hasLogin()):?> 登陆才可以看到这里的内容 <?php endif;?>文章作者名称与主页地址<a href="<?php $this->author->permalink(); ?>"><?php $this->author(); ?>文章最后编辑时间<?php echo gmdate('Y-m-d H:i', $this->modified + Typecho_Widget::widget('Widget_Options')->timezone); ?>当前文章id<?php $this->cid(); ?>文章中的上一篇和下一篇上一篇: <?php $this->thePrev('%s','没有了'); ?> 下一篇: <?php $this->theNext('%s','没有了'); ?>文章标签<?php $this->tags(', ', true, 'none'); ?> 说明：(', ', true, 'none')第一个单引号间的逗号代表标签与标签的间隔用逗号隔开，true是标签以超链接形式输出，none为该文章没有标签时显示的提示信息。用户昵称<?php $this->user->screenName(); ?>后台地址与登陆地址<?php $this->options->adminUrl(); ?>//后台地址 <?php $this->options->adminUrl('login.php'); ?>//登陆地址分类描述<?php echo $this->getDescription(); ?>标签相关文章<?php $this->related(5)->to($relatedPosts); ?> <?php while ($relatedPosts->next()): ?> <a href="<?php $relatedPosts->permalink(); ?>" title="<?php $relatedPosts->title(); ?>"><?php $relatedPosts->title(); ?> <?php endwhile; ?> 调用某分类文章，pageSize是数量，mid是分类号：<?php $this->widget('Widget_Archive@index', 'pageSize=6&type=category', 'mid=47′) ->parse(' {title} '); ?>首行缩进问题,加入css实现.post-content p{ text-indent: 2em; /*em是相对单位，2em即现在一个字大小的两倍*/ } 最新文章<?php $this->widget('Widget_Contents_Post_Recent')->to($post); ?> <?php while($post->next()): ?> <a href=”<?php $post->permalink(); ?>” title=”<?php $post->title(); ?>”> <?php $post->title(25, '…'); ?> <?php endwhile; ?>神奇的is语法<?php if ($this->is('post')) : ?> 这里就是内容了 <?php endif; ?> typecho可以使用is语法判断很多东西，比如 $this->is('index'); $this->is('archive'); $this->is('single'); $this->is('page'); $this->is('post'); $this->is('category'); $this->is('tag'); 甚至是 $this->is('category', 'default'); $this->is('page', 'start'); $this->is('post', 1);判断为当前页的第几篇文章，并单独输出内容<?php if ($this->sequence == 0): ?> //需要的插入 <?php endif; ?>总访问量首先，在functions.php里加入如下代码：//门前大路上，走过一群小伙伴，快来数一数：2，4，6，7，8…… function theAllViews() { $db = Typecho_Db::get(); $row = $db->fetchAll('SELECT SUM(VIEWS) FROM `typecho_contents`'); echo number_format($row[0]['SUM(VIEWS)']); }然后用下面代码调用：<?php echo theAllViews();?>例如：你是第<?php echo theAllViews();?>位相遇的小伙伴网站运行时间一、PHP调用首先，在functions.php里加入如下代码：// 设置时区 date_default_timezone_set('Asia/Shanghai'); /** * 秒转时间，格式 年 月 日 时 分 秒 * */ function getBuildTime() { // 在下面按格式输入本站创建的时间 $site_create_time = strtotime('2019-06-23 00:00:00'); $time = time() - $site_create_time; if (is_numeric($time)) { $value = array( "years" => 0, "days" => 0, "hours" => 0, "minutes" => 0, "seconds" => 0, ); if ($time >= 31556926) { $value["years"] = floor($time / 31556926); $time = ($time % 31556926); } if ($time >= 86400) { $value["days"] = floor($time / 86400); $time = ($time % 86400); } if ($time >= 3600) { $value["hours"] = floor($time / 3600); $time = ($time % 3600); } if ($time >= 60) { $value["minutes"] = floor($time / 60); $time = ($time % 60); } $value["seconds"] = floor($time); echo ''.$value['years']. '年'.$value['days']. '天'.$value['hours']. '小时'.$value['minutes']. '分'; } else { echo ''; } }然后用下面代码调用：<?php getBuildTime(); ?>二、JS调用直接在模板文件里添加以下两种样式的任意一种样式一本站已安全运行: 样式二