在使用 Debian 时,发现通过 Vi 编辑文件时不能使用方向键,解决办法如下:
第一种方法:
在终端打开VI配置文件:vi ~/.vimrc
输入:set nocompatible
保存后,vi 就可以使用上下左右方向键了。
第二种方法:
安装 vim ,执行 sudo apt install vim
,安装完成后,vi 命令就可以使用方向键了。
在使用 Debian 时,发现通过 Vi 编辑文件时不能使用方向键,解决办法如下:
第一种方法:
在终端打开VI配置文件:vi ~/.vimrc
输入:set nocompatible
保存后,vi 就可以使用上下左右方向键了。
第二种方法:
安装 vim ,执行 sudo apt install vim
,安装完成后,vi 命令就可以使用方向键了。
第一步,执行安装命令:
apt install -y mariadb-server
第二步,执行如下命令进行安全配置,该命令可以配置数据库密码等相关操作。
mysql_secure_installation
通过如下命令授权 root 用户远程访问,xxxxx 是密码。
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'xxxxxx';
然后进入 /etc/mysql/mariadb.conf.d,编辑 50-server.cnf。
注释掉下面的行(在前面加#)
bind-address = 127.0.0.1
最后重启服务即可。
systemctl restart mysql
提示:
由于mysql/mariadb配置文件有点多,如果找不到该配置在哪个文件里面,可以通过如下命令进行查找:
grep -r "bind-address" /etc/mysql/*
今天给一台国内的服务器重装了 debian 11 ,由于 debian 11 带的 php 版本是 7.4,有点老,所以我们可以使用 debian 开发者 Ondřej Surý 维护的 php 源 deb.sury.org 。具体用法如下:
首先,使用下面的命令安装所须的软件包:
apt install ca-certificates apt-transport-https software-properties-common -y
安装所须软件包后,使用以下命令将 Sury 存储库添加到 APT:
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/sury-php.list
然后,使用以下命令下载并添加 GPG 密钥:
wget -qO - https://packages.sury.org/php/apt.gpg | apt-key add -
上述添加 GPG 密钥的命令会提示 Warning: apt-key is deprecated
,但是可以执行成功,如果不想要报 Warning 可以换成下面的命令:
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
完成后,使用以下命令更新存储库:
apt update
到此,sury 源添加完成。
如果要安装 php 的最新版本,可以执行:
apt install php-fpm php-mysql php-mbstring php-curl php-dom php-imagick php-zip php-gd php-intl
如果要安装指定的版本,例如安装 php8.0,可以执行:
apt install php8.0-fpm php8.0-mysql php8.0-mbstring php8.0-curl php8.0-dom php8.0-imagick php8.0-zip php8.0-gd php8.0-intl
为了能让 WordPress 发送通知邮件,需要在服务器上配置MTA(Mail Transfer Agent),常见的MTA服务有 Sendmail、Postfix 等。
Sendmail 是 Unix 系统的标准邮件传输代理,而 Postfix 邮件服务器安全性更好一些。
这里我们选择的是 Postfix,用来为 WordPress 提供仅发送服务。
通过如下命令安装 Postfix
apt install postfix
安装过程中,会出现配置界面。如果已安装,可以使用 dpkg-reconfigure postfix
重新打开该界面。
我们将选择 Internet Site 并按回车。
对于系统邮件名称,我们将使用我们网站的域名,对于本站,就是 wujie.me 。
这两步配置完后,等待安装完成,WordPress 就可以发送通知邮件了。
如果想对 Postfix 进行更详细的配置,可以配置文件 /etc/postfix/main.cf。
例如为了增强安全性,需要把 SMTP 服务改为只允许本地使用,那么可以把 inet_interfaces = all
改成 inet_interfaces = loopback-only
改完之后,需要重启 postfix 服务:
systemctl restart postfix
在网站根目录下执行(针对debian/ubuntu,这俩系统的php-fpm用户名是www-data)
for directories
//language:bash
find . -type d -print0 | xargs -0 chmod 0755
for files
//language:bash
find . -type f -print0 | xargs -0 chmod 0644
//language:bash
chmod 600 wp-config.php
//language:bash
chown -R www-data:www-data *
如果wordpress站点健康检查提示无法自动更新,则执行下面这句,把当前文件夹也加入php-fpm用户组
//language:bash
chown -R www-data:www-data .
在使用自定义文章类型时,对应的 category 页面的文件名应该是taxonomy-{taxonomy}.php
。
例如有一个自定义 Post Type 的分类法是 product_category,那么该分类法对应的 category 页面的模板文件名就是taxonomy-product_category.php
。
如果该分类法下有一个分类,名为adva
,那么该分类对应的模板文件名为taxonomy-product_category-adva.php
。
如果是默认的文章类型,即 post type 是 post ,它的 category 页面的名字就是category.php
,默认的分类法其实就是category
,但却不能写成taxonomy-category
,只能自定义类型才能这么写。
如果默认分类法下有一个news
的分类,那么对应的模板文件名就是category-news.php
。
一个post type可以没有分类(category),但一定可以进行文章归档(archive)。
分类(category),是针对分类法(taxonomy)的,而归档而是针对文章的。
所以,模板命名上,category 总是和分类关联,比如news分类模板:category-news.php。
而 archive 总是和 post type 关联,比如有一个 custom post type 名字是 product,那么对应的归档页面就是 archive-product.php。
本想这个功能应该不难,但却费了好些工夫。
在wordpress中想要实现点击下载,有两种方法
1、在下载链接上增加 `download=””` 属性
<a href="<?php echo $download_url; ?>" download="">下载</a>
但是这种方法查资料发现,只支持chrome和firefox,兼容性不好。
2、第二种方法也是费了好大劲才查找到的资料,直接上代码
<?php
// add the download ID query var which we'll set in the rewrite rule
function wpd_query_var($query_vars) {
$query_vars[] = 'download_id';
return $query_vars;
}
add_filter('query_vars', 'wpd_query_var');
// add rewrite rule
function wpd_rewrite() {
add_rewrite_rule(
'download/([0-9]+)/?$',
'index.php?download_id=$matches[1]',
'top'
);
}
add_action('init', 'wpd_rewrite');
// check for download_id and output the file
function wpd_request($wp) {
if (array_key_exists('download_id', $wp->query_vars)) {
// 在此实现下载代码的书写
// output your headers and file here
// ID is in $wp->query_vars['download_id']
// then exit to halt any further execution
$download_id = $wp->query_vars['download_id'];
$filename = get_attached_file($download_id);
if (file_exists($filename)) {
include get_template_directory() . '/inc/download.php';
downloadFile($filename);
} else {
wp_die(__('要下载的文件不存在!'));
}
}
}
add_action('parse_query', 'wpd_request');
下载时,引用了一个inc目录下的download.php,代码如下:
<?php
/**
* @param $filePath //下载文件的路径
* @param int $readBuffer //分段下载 每次下载的字节数 默认1024bytes
* @param array $allowExt //允许下载的文件类型
* @return void
*/
function downloadFile($filePath, $readBuffer = 1024, $allowExt = ['jpeg', 'jpg', 'peg', 'gif', 'zip', 'rar', 'txt', 'pdf']) {
//检测下载文件是否存在 并且可读
if (!is_file($filePath) && !is_readable($filePath)) {
return false;
}
//检测文件类型是否允许下载
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
if (!in_array($ext, $allowExt)) {
return false;
}
//设置头信息
//声明浏览器输出的是字节流
header('Content-Type: application/octet-stream');
//声明浏览器返回大小是按字节进行计算
header('Accept-Ranges:bytes');
//告诉浏览器文件的总大小
$fileSize = filesize($filePath); //坑 filesize 如果超过2G 低版本php会返回负数
header('Content-Length:' . $fileSize); //注意是'Content-Length:' 非Accept-Length
//声明下载文件的名称
// $useragent = $_SERVER['HTTP_USER_AGENT'];
// if (strpos($useragent, 'baiduboxapp')) {
// $encoded_filename = $filePath;
// } else {
// $encoded_filename = urlencode($filePath);
// $encoded_filename = str_replace("+", "%20", $encoded_filename);
// }
header('Content-Disposition:attachment;filename=' . basename($filePath)); //声明作为附件处理和下载后文件的名称
//获取文件内容
$handle = fopen($filePath, 'rb'); //二进制文件用‘rb’模式读取
while (!feof($handle)) { //循环到文件末尾 规定每次读取(向浏览器输出为$readBuffer设置的字节数)
echo fread($handle, $readBuffer);
}
fclose($handle); //关闭文件句柄
exit;
}
这样,下载链接只要按如下写法即可实现下载:
<a href="/download/<?php echo $ids[$i]; ?>">点击下载</a>
$ids[$i]
表示wordpress附件的id
3、注意到还有一种方式似乎代码更少一些,代码如下:
<?php
add_action('init', function () {
add_rewrite_endpoint('download', EP_ROOT);
add_action('template_redirect', function () {
if ($pid = get_query_var('download')) {
$found = false;
if ($file = wp_get_attachment_image_src(absint($pid), 'full')) {
$found = true;
header("Content-Disposition: attachment; filename=" . basename($file[0]));
readfile($file[0]);
exit();
}
if (!$found)
wp_die(__('Image file not found!'));
}
});
});
但是这种方式只适合下载图片文件,可以把它改造一下,用来下载所有文件,改造后的代码如下:
<?php
add_action('init', function () {
add_rewrite_endpoint('download', EP_ROOT);
add_action('template_redirect', function () {
if ($pid = get_query_var('download')) {
$found = false;
// 根据附件ID查询附件的真实路径
$filename = get_attached_file($pid);
if (file_exists($filename)) {
$found = true;
header("Content-Disposition: attachment; filename=" . basename($filename));
readfile($filename);
exit();
}
if (!$found)
wp_die(__('Image file not found!'));
}
});
});
然后使用这种链接即可实现下载https://lwbj.cn/download/123/
,123
表示附件的ID
和第二种方法,思路是一样的,都是添加通过URL重写规则,然后拦截该URL以实现下载功能。但是第三种方法代码更简练一些。
只需要在register_taxonomy
函数的第三个参数中,添加show_admin_column=>true
即可。代码如下:
<?php
/**
* 为产品 post type 添加分类功能
*/
add_action('init', 'my_taxonomies_product', 0);
function my_taxonomies_product() {
$labels = array(
'name' => _x('产品分类', 'taxonomy 名称'),
'singular_name' => _x('产品分类', 'taxonomy 单数名称'),
'search_items' => __('搜索产品分类'),
'all_items' => __('所有产品分类'),
'parent_item' => __('该产品分类的上级分类'),
'parent_item_colon' => __('该产品分类的上级分类:'),
'edit_item' => __('编辑产品分类'),
'update_item' => __('更新产品分类'),
'add_new_item' => __('添加新的产品分类'),
'new_item_name' => __('新产品分类'),
'menu_name' => __('产品分类'),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'show_admin_column' => true,
);
register_taxonomy('product_category', 'product', $args);
}
如果要在列表中添加自定义字段,即wp_postmeta表中的字段(通过meta_box添加的),可以使用下面的代码:
<?php
// 在列表中把加的字段显示出来
add_action("manage_posts_custom_column", "product_custom_columns");
function product_custom_columns($column) {
global $post;
switch ($column) {
case "product_director":
echo get_post_meta($post->ID, '_product_director', true);
break;
}
}
add_filter("manage_edit-product_columns", "movie_edit_columns");
function movie_edit_columns($columns) {
$columns['product_director'] = '产品分类';
return $columns;
}
只需要在register_taxonomy
函数的第三个参数中,添加show_admin_column=>true
即可。代码如下:
<?php
/**
* 为产品 post type 添加分类功能
*/
add_action('init', 'my_taxonomies_product', 0);
function my_taxonomies_product() {
$labels = array(
'name' => _x('产品分类', 'taxonomy 名称'),
'singular_name' => _x('产品分类', 'taxonomy 单数名称'),
'search_items' => __('搜索产品分类'),
'all_items' => __('所有产品分类'),
'parent_item' => __('该产品分类的上级分类'),
'parent_item_colon' => __('该产品分类的上级分类:'),
'edit_item' => __('编辑产品分类'),
'update_item' => __('更新产品分类'),
'add_new_item' => __('添加新的产品分类'),
'new_item_name' => __('新产品分类'),
'menu_name' => __('产品分类'),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'show_admin_column' => true,
);
register_taxonomy('product_category', 'product', $args);
}
如果要在列表中添加自定义字段,即wp_postmeta表中的字段(通过meta_box添加的),可以使用下面的代码:
<?php
// 在列表中把加的字段显示出来
add_action("manage_posts_custom_column", "product_custom_columns");
function product_custom_columns($column) {
global $post;
switch ($column) {
case "product_director":
echo get_post_meta($post->ID, '_product_director', true);
break;
}
}
add_filter("manage_edit-product_columns", "movie_edit_columns");
function movie_edit_columns($columns) {
$columns['product_director'] = '产品分类';
return $columns;
}