标签: PHP

  • 从Typecho安全平移到WordPress

    这里不比较Typecho与Wordpress的好坏。实际上优缺点都很明显。但如果你没有其他想法,只是想单纯写写内容,Notebook才是最棒的选择。我只是想把加的各位朋友的友链放在除了友链页以外的其他页面,那貌似只能放在sidebar了,所以选择了一个双栏的杂志主题。后来想了想,直接换wordpress得了。

    1. 导出数据

    数据导出当然使用的是ByTyp,但是我记得之前第一次安装是有什么问题的,貌似是PHP版本不对还是什么东西,忘记了,不过我记得我修改了一些东西。如果你会有这个问题并且你发现搜索不到解决方案,你可以点下面的按钮下载我的备份:

    2. 备份

    备份你需要做以下备份

    • 下载Typecho的所有文件内容
    • 下载Typecho的数据库备份文件
    • 尝试新建数据库并导入数据库备份文件查看是否可以导入
    • 使用Typecho的备份功能下载备份文件
    • 检查以上备份

    3. 安装Wordpress和导入数据

    因为我后端使用的是宝塔,所以有一键部署。我的域名是banzhuanriji.com,我新建的网站绑定的域名为abc(这里你自己设置).banzhuanriji.com,然后所有的操作都是在这个网站上进行的。

    工具-导入-立即安装,安装完成后会显示【运行导入器】,然后选择上面ByTyp导出的文件即可,选择接受用户即可。

    4. 修改域名

    1. 检查上面的备份内容
    2. wordpress后台,设置-常规:WordPress 地址(URL)和 站点地址(URL)修改为你的地址
    3. 修改网站文件夹名称,也就是删除原来的 banzhuanriji.com,把abc.banzhuangriji.com,修改为banzhuanriji.com
    4. 重启Nginx

    5. 安装需要的插件

    我是所有都设置好之后才修改域名的,现在我点击主题的自定义,就会先显示几条错误提示,再显示自定义网页页面。错误内容如下:

    
    Warning: Undefined array key "mp_featuredimg_1" in /www/wwwroot/banzhuanriji.com/wp-includes/class-wp-customize-widgets.php on line 1130
    
    Warning: Trying to access array offset on value of type null in /www/wwwroot/banzhuanriji.com/wp-includes/class-wp-customize-widgets.php on line 1130
    
    Warning: Undefined array key "mp_featuredimg_1" in /www/wwwroot/banzhuanriji.com/wp-includes/class-wp-customize-widgets.php on line 1131
    
    Warning: Trying to access array offset on value of type null in /www/wwwroot/banzhuanriji.com/wp-includes/class-wp-customize-widgets.php on line 1131
    
    Warning: Undefined array key "mp_featuredimg_1" in /www/wwwroot/banzhuanriji.com/wp-includes/class-wp-customize-widgets.php on line 603
    
    Warning: Trying to access array offset on value of type null in /www/wwwroot/banzhuanriji.com/wp-includes/class-wp-customize-widgets.php on line 603

    貌似是Blocky插件的问题,到现在我都不知道怎么解决…

    6. 其他

    关于安装的插件和主题,有兴趣的话可以查看关于页面。

    如果你没有想使用Wordpress,那么我推荐你使用Tp2MD,可以导出到Markdown文件,你经过简单的修改可以直接在一些hexo,hugo,nextjs或者astro等可以使用Markdown文件的博客系统。

  • 在vercel上部署typecho

    TL;DR

    通过vercel第三方库来运行php程序

    效果展示

    展示不了一点,我发现部署几天后开始变得非常卡,不知道为啥

    所以我推荐你每天定时deploy一下,会好很多

    一,注册需要的账号

    你需要注册以下账号

    • github
    • vercel
    • 一个免费或者你自己搭建的mysql数据库

    关于数据库,不推荐使用国内的免费数据库,因为vercel访问太慢了
    或许你可以尝试db4free,或者一些免费空间提供的数据库

    二,操作步骤

    1. 创建git仓库

    在github创建一个仓库,注意这个仓库需要是private的,也就是私密的仓库。然后clone到本地。下面为了方便,假设仓库名为blog

    2. 下载typecho

    下载地址:https://typecho.org/download

    3. 把typecho解压到仓库文件夹内

    此时文件应该存放在根目录

    4. 新建api文件夹,然后在api文件夹下创建index.php文件

    其中index.php文件的内容如下

    <?php
    $file= __DIR__ . '/..'.$_SERVER["PHP_SELF"];
    
    if(file_exists($file))
    {
       return false;
    }
    else
    {
        require_once __DIR__ . '/../index.php';
    }
    #echo $_SERVER["PHP_SELF"];

    5. 在仓库中创建vercel.json

    内容如下

    {
      "functions": {
        "api/index.php": {
          "runtime": "vercel-php@0.7.3"
        }
      },
      "routes": [{ "src": "/(.*)", "dest": "/api/index.php" }]
    }

    6. 在根目录创建config.inc.php

    内容如下

    <?php
    /**
     * Typecho Blog Platform
     *
     * @copyright  Copyright (c) 2008 Typecho team (http://www.typecho.org)
     * @license    GNU General Public License 2.0
     * @version    $Id$
     */
    
    /** 开启https */
    define('__TYPECHO_SECURE__',true);
    
    /** 定义根目录 */
    define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
    
    /** 定义插件目录(相对路径) */
    define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
    
    /** 定义模板目录(相对路径) */
    define('__TYPECHO_THEME_DIR__', '/usr/themes');
    
    /** 后台路径(相对路径) */
    define('__TYPECHO_ADMIN_DIR__', '/admin/');
    
    /** 设置包含路径 */
    @set_include_path(get_include_path() . PATH_SEPARATOR .
    __TYPECHO_ROOT_DIR__ . '/var' . PATH_SEPARATOR .
    __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__);
    
    /** 载入API支持 */
    require_once 'Typecho/Common.php';
    
    /** 程序初始化 */
    Typecho_Common::init();
    
    /** 定义数据库参数 */
    $db = new Typecho_Db('Pdo_Mysql', 'typecho_');
    $db->addServer(array (
      'host' => '数据库地址',
      'user' => '数据库用户',
      'password' => '数据库密码',
      'charset' => 'utf8mb4',
      'port' => '3306',
      'database' => '数据库名',
      'engine' => 'MyISAM',
    ), Typecho_Db::READ | Typecho_Db::WRITE);
    Typecho_Db::set($db);

    7. 注释掉会阻挡操作的内容

    打开根目录下的install.php文件,注释或者删除773-775行,注释的内容大概如下。

        // if (!$writeable) {
            // $errors[] = _t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', $uploadDir);
        // }

    这里如果没有删除,可能会无法初始化数据库

    8. 上传代码,在vercel中编译,注意提前绑定域名

    9. 第一次打开会报错

    提示Database Query Error。这时你需要在你的域名||vercel提供的免费域名后添加/install.php,然后按照步骤操作。

    这里如果你没有执行第7步的操作,可能会报错,建议修改之后重新提交

    三,注意事项

    1. 过长的等待时间会触发vercel报错,提示This Serverless Function has timed out. 这时你或许可以考虑更换数据库
    2. 注意看第7点
    3. 一些函数官方说支持,但是会有奇怪的问题
    4. 上传二进制文件和直接修改文件的功能就别想了,在仓库中操作吧
    5. 暂时想不到了
  • 用PHP做一个自己的访问统计

    原因

    为什么自己写

    因为在自己域下,可控&不会被常见的去广告插件屏蔽

    为什么选择PHP

    我曾经试图用CSS方法实现,奈何技术有限,且我不是专业的前端和后端。不过如果有兴趣的朋友可以看看这个文章 https://herman.bearblog.dev/how-bear-does-analytics-with-css/ 。这个作者简单介绍了自己如何使用CSS方法进行统计并计算PV之类的数据。

    且我希望是放在主题文件下可以直接运行和使用,没有想在服务端运行docker或者其他程序

    它有什么功能

    机制简单的统计,访问+1,刷新+1,如此而已

    开始

    创建数据库

    首先你需要创建数据库,如果你有数据库的前提下,请使用下面的语句新建一张这样的表:

    CREATE TABLE statistics (
        id INT AUTO_INCREMENT PRIMARY KEY,
        site_name VARCHAR(255) NOT NULL,
        visit_count BIGINT NOT NULL DEFAULT 0
    );

    这个表里只包含了一个网站地址和这个网站相对应的访问数量。它的结构大概是:

    sitename visit_count
    banzhuanriji.com 123

    然后我们初始化一下:

    INSERT INTO statistics (site_name, visit_count) VALUES ('banzhuanriji.com', 0);

    新建一行banzhuanriji.com的数据,且把默认数据(访问量)设置为0

    实现代码

    首先在你的主题目录下创建一个counter.php的文件,文件内容如下

    <?php
    $servername = "localhost";
    $username = "statistics";
    $password = "password";
    $dbname = "statistics";
    
    // 创建连接
    $conn = new mysqli($servername, $username, $password, $dbname, 3306);
    
    // 检查连接
    if ($conn->connect_error) {
        die("连接失败,请稍后再试。");
    }
    
    // 指定网站名称
    $site_name = 'banzhuanriji.com'; // 这里修改为需要统计的网站名称
    
    // 更新浏览次数
    $sql = "UPDATE statistics SET visit_count = visit_count + 1 WHERE site_name = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $site_name); // 绑定网站名称
    $stmt->execute();
    
    // 获取当前浏览次数
    $sql = "SELECT visit_count FROM statistics WHERE site_name = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $site_name); // 绑定网站名称
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    $current_views = $row['visit_count'] ?? 0; // 如果没有找到,默认值为 0
    
    // 关闭连接
    $stmt->close();
    $conn->close();
    ?>
    
    <br>当前浏览次数: <?php echo htmlspecialchars($current_views); ?>

    然后你只需要在需要的地方引用counter.php即可。下面依然以final主题为示例:

    <?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
    
    <footer style="margin:50px 0px">
    
    <span id="footer-directive">
    
    <?php $this->options->addfoot() ?>
    
    </span>
    
    <span>
    
    &copy; 2024 <a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title(); ?></a>
    
    </span>
    <?php include 'counter.php'; ?>
    </footer>
    
    </body>
    
    </html>

    然后就可以实现类似卜蒜子一样的统计效果了。而且没有使用到JS,不会被去广告插件拦截。

    其它

    如果你有兴趣可以自己动手实现一下。你也可以把数据库信息替换成typecho的数据库信息,这样就避免了新操作一个数据库的逻辑,并且可以实现使用typecho的Db.php文件操作数据库。下面给一个简单的示例,具体的实现逻辑和读写权限请自行斟酌完成。

    <?php
    // 引入 Typecho 的数据库类
    require_once '/www/wwwroot/banzhuanriji.com/usr/Typecho/Db.php'; // 确保路径正确
    
    // 获取数据库连接
    $db = Typecho_Db::get();
    
    // 指定网站名称
    $site_name = 'example.com'; // 这里修改为需要统计的网站名称
    
    try {
        // 更新特定网站的浏览次数
        $db->query("UPDATE `statistics` SET `visit_count` = `visit_count` + 1 WHERE `site_name` = ?", $site_name);
    
        // 获取当前浏览次数
        $result = $db->fetchRow($db->select('visit_count')->from('statistics')->where('site_name = ?', $site_name));
        $current_views = $result['visit_count'];
    } catch (Exception $e) {
        // 处理异常
        error_log($e->getMessage());
        $current_views = 0; // 如果出错,设置为 0
    }
    ?>
    
    <div class="counter">
        <h1><?php echo htmlspecialchars($site_name); ?> 当前浏览次数: <?php echo htmlspecialchars($current_views); ?></h1>
    </div>