分类: 编程

  • PHP文件上传$_FILES无内容

    一般是以下两个参数的配置问题。

    upload_max_filesize='100M'
    post_max_size='100M'

  • 网页、APP跳转应用商店

    安卓

    1. 跳转到应用页面:market://details?id=
    2. 跳转到搜索:market://search?q=

    IOS

    1. 应用页面:itms-apps://itunes.apple.com/app/id 114211089
  • MySQL给已存在的主键字段添加自增AUTO_INCREMENT

    每次都记不起来,记录一下…

    # 添加自增约束
    alter table table_name modify column COLUMN_NAME COLUMN_TYPE auto_increment;
    # 配置自增起始值
    alter table table_name auto_increment=10000;
  • PHP中对象缓存方式的选择

    类似于Map的键值类型对象缓存对于提高应用的性能有很大的作用,实现此类缓存的方式也比较多,那么该如何选择对象缓存的方式呢?由于PHP常用的运行方式主要是基于FPM的形式,这篇文章暂不考虑常驻内存形式的缓存。

    (更多…)
  • WordPress常用插件

    WordPress提供了完善的插件机制,通过使用插件,我们可以优化Wordpress的性能、丰富Wordpress的功能,但是插件市场的插件实现也良莠不齐的,记录一些使用体验优秀的插件,主要推荐官方的插件。

    (更多…)
  • 如何将网站权重提升到1

    在Google中,网站的权重(或者说“PageRank”)是一个页面的重要性的度量。它基于链接,也就是其他页面指向该页面的链接。当搜索引擎(比如Google)找到一个页面时,它会对该页面进行评估,并根据该页面的链接数量和质量来决定其权重。权重高的页面通常会在搜索结果中排名更高。

    (更多…)
  • WordPress/woocommerce性能优化

    默认安装的 WordPress 性能表现很一般,尤其如果添加了 woocommerce 插件后,后台总有一种卡顿的感觉,为了提升 WordPress/woocommerce 的使用体验,需要进行一些性能优化操作。WordPress 本身是一个基于 PHP 实现的程序,因此要优化使用体验就要在 LNMP/LAMP 架构的组件配置上进行调整。这篇文章介绍一些 LNMP 架构中,对于 WordPress 性能有影响的配置项,理论上应该也适用于其他 PHP 项目。

    (更多…)
  • SEO如何优化网站标题

    网站标题是SEO优化中非常重要的一部分,以下是一些可以优化网站标题的建议:

    (更多…)
  • How to calculate the similarity of two articles using PHP

    How to calculate the similarity of two articles using PHP?

    (更多…)
  • HTTP status and The meaning

    Here are some of the most common HTTP status codes and their meanings:

    (更多…)
  • How to improve wordpress performance


    There are a number of things you can do to improve the performance of your WordPress site:

    (更多…)
  • APP分发前的准备工作

    1. 登录、注册、注销
    2. 隐私权政策和服务协议
    3. 登录注册页面弹窗(勾选已读服务协议和隐私权政策,弹窗动作必须)
    4. 应用市场和对应账号
      • 苹果开发者会员
      • 主体认证
      • 涉及收费可能需要ICP证
    5. 软著登记证
  • 如何避免WordPress/Woocommerce网站被黑

    WordPress本身的安全性相对来说还是值得信任的,但是依然还是有一些缺点,那么如何避免Wordpress站点被黑呢?我们来看看纯净Wordpress站点存在的一些安全隐患吧。

    (更多…)
  • 使用typescript开发chrome扩展

    记录一下使用typescript开发chrome扩展的相关配置。

    1. 安装依赖

    必定需要用到的开发依赖项:

    • chrome-types
    • copy-webpack-plugin
    • ts-loader
    • typescript
    • webpack-cli
    npm install chrome-types webpack-cli ts-loader typescript copy-webpack-plugin --save-dev

    2. 打包配置

    2.1 首先创建ts配置文件

    npx tsc --init

    2.2 创建webpack打包配置文件

    const path = require('path');
    const CopyPlugin = require("copy-webpack-plugin");
    
    module.exports = {
      mode: 'production',
      entry: {
        index: {
          import: './src/index.ts',
          filename: 'index.js'
        },
        background: {
          import: './src/background.ts',
          filename: 'background.js'
        }
      },
      plugins: [
        new CopyPlugin({
          patterns: [
            { from: "public", to: "" },
          ],
        }),
      ],
      module: {
        rules: [
          {
            test: /.tsx?$/,
            use: 'ts-loader',
            exclude: /node_modules/,
          },
        ],
      },
      resolve: {
        extensions: ['.tsx', '.ts', '.js'],
      },
      output: {
        clean: true
      },
    };

    3. 配置打包命令

    "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "build": "webpack build"
      }

    4. 基本目录结构截图

    chrome使用typescript目录结构
    chrome使用typescript目录结构
  • 为什么股市做空比做多危险

    做空和做多都是金融市场中的一种交易策略,但是它们的风险是不同的。以下是一些原因,说明为什么做空比做多危险:

    (更多…)
  • how to improve the rank of search results in google

    There are many factors that affect a website’s ranking in Google search results, but some of the most important include:

    (更多…)
  • php: /usr/local/lib/libcurl.so.4: no version information available (required by php)

    出现原因是安装了多个版本的库,ubuntu的一些库似乎增加了一些附加补丁,导出的符号与ubuntu有关联的版本信息,但在标准的库中是没有的。

    (更多…)
  • use multiple simple queries or a join

    The decision of whether to use multiple simple queries or a join depends on the specific requirements of the query.

    (更多…)
  • Windows rclone挂载sftp

    手动挂载命令:

    rclone mount sftp:/mnt o: --cache-dir %SystemRoot%TEMP --allow-other --vfs-cache-mode writes --vfs-cache-max-age 60s  --allow-non-empty

    创建服务:

    // 安装nssm
    winget install nssm
    
    // 创建服务
    nssm install rclone

    配置信息(具体路径需要根据实际情况来确定):

    Path: C:UsersAdministratorDocumentsbinrclone.exe
    Arguments: mount config:/root A: --volname sftp --config C:UsersAdministratorAppDataRoamingrclonerclone.conf

    遇到的问题

    1. 无法修改文件

    是因为nssm默认使用LocalSystem用户。

    任务管理器-服务-右键rclone选择打开服务->找到rclone右键选择属性->登录->选择此账户->点击右侧浏览->弹出框中选择高级->立即查找->选择一个本地账户比如Adminstrator->一路确定。

  • 使用WordPress作为小程序后端——小程序请求前置检查

    小程序默认提供了一个固定格式的referer格式,具体可以参考官方文档:网络请求。如下:

    https://servicewechat.com/{appid}/{version}/page-frame.html

    由于这个referer是不可以手动设置的,因此透过这个referer,我们可以对请求进行一个简单的前置检查,过滤一些简单的脚本。同时,我们也能通过这个前置检查来了解请求的身份,即小程序APPID,当需要同时支持多个小程序时,这一点还是很有意义的。

    一个简单实现

    /**
     * 小程序请求通用前置检查
     */
    function precheck($referer) {
        $result = preg_match("/^https://servicewechat.com/(.*?)/(.*?)/page-frame.html$/", $referer, $matches);
        if (!$result || empty($matches) || !isset($matches[1]) || !isset($matches[2])) {
            return false;
        }
    
        return true;
    }

    在Wordpress中的使用

    通过这个简单的函数,我们可以对小程序发起的请求进行一个简单的前置检查。那么如何应用到Wordpress中呢?

    通过阅读Wordpress的文档,可以了解注册rest路由的函数是register_rest_route,具体参考文档:register_rest_route。注册路由可以配置三个回调函数,分别是permission_callback,validate_callback和callback。我觉得这个检查更适合用在permission_callback,即当无法通过检查的时候,我们实际上可以认为这是一个非法请求,我们对之前的实现进行一些修改:

    /**
     * 小程序请求通用前置检查
     */
    function precheck(WP_REST_Request $request) {
        $referer = $request->get_header('referer');
        $result = preg_match("/^https://servicewechat.com/(.*?)/(.*?)/page-frame.html$/", $referer, $matches);
        if (!$result || empty($matches) || !isset($matches[1]) || !isset($matches[2])) {
            return false;
        }
    
        return true;
    }

    暂存获取到的APPID和VERSION,方便之后使用

    在前面的代码里,我们通过一个简单的正则,对referer进行了一个简单的检查,但是匹配的一些结果我们没有暂存下来,为了方便之后获取APPID和VERSION信息,我们再次扩展一下:

    /**
     * 小程序请求通用前置检查
     */
    function precheck(WP_REST_Request $request) {
        $referer = $request->get_header('referer');
        $result = preg_match("/^https://servicewechat.com/(.*?)/(.*?)/page-frame.html$/", $referer, $matches);
        if (!$result || empty($matches) || !isset($matches[1]) || !isset($matches[2])) {
            return false;
        }
    
        $request->set_attributes([
            'app_id' => $matches[1],
            'version' => $matches[2]
        ]);
    
        return true;
    }

    封装

    为了更方便使用,我们再次进行一点简单的封装。

    /**
     * 给所有的路由添加默认的前置检查钩子
     */
    function register_wechat_mp_rest_route($route_namespace, $route, $args = [], $override = false) {
        add_filter( 'wechat_mp_permission_callback', precheck, 10, 2 );
    
        if (isset($args['permission_callback'])) {
            if (!is_array($args['permission_callback'])) {
                $args['permission_callback'] = [ $args['permission_callback'] ];
            }
    
            foreach ($args['permission_callback'] as $callback) {
                add_filter( 'wechat_mp_permission_callback', $callback, 10 , 2 );
            } 
        }
        $args['permission_callback'] = function (WP_REST_Request $request) {
            return apply_filters( 'wechat_mp_permission_callback', true, $request );
        };
        return register_rest_route($route_namespace, $route, $args, $override);
    }
    
    /**
     * 小程序请求通用前置检查
     */
    function precheck($permission, WP_REST_Request $request) {
        if ($permission === false) {
            return false;
        }
    
        $referer = $request->get_header('referer');
        $result = preg_match("/^https://servicewechat.com/(.*?)/(.*?)/page-frame.html$/", $referer, $matches);
        if (!$result || empty($matches) || !isset($matches[1]) || !isset($matches[2])) {
            return false;
        }
    
        $request->set_attributes([
            'app_id' => $matches[1],
            'version' => $matches[2]
        ]);
    
        return true;
    }

    好,到这里,我们的前置检查相关的代码就完成了。下一篇的时候我们来实现一下用户认证。