如何在cPanel的Cron Job中访问其他脚本的变量或函数?
我是Cron Job新手,正在配置测试任务熟悉它的运作方式。我在cPanel里创建了这样的任务:
wget -O - -q https://website.com/staging/wp-content/themes/AT103/test-cron.php
我的测试脚本test-cron.php内容很简单:
<?php $email_to = "info@domain.com"; $title = "Test title"; $body = "Test body"; mail($email_to, $title, $body); ?>
这个测试任务运行正常,我能按设定的间隔收到邮件。
我的网站支持用户发布商品售卖广告/列表,我想通过Cron Job遍历所有列表,给已过期列表的买卖双方发邮件。第一步需要访问网站里的变量(比如存储列表对象的$post变量)或者调用相关函数。
我试着在test-cron.php顶部加代码调用同目录下的functions.php文件(每次只试一种写法):
require '/functions.php'; require 'https://website.com/staging/wp-content/themes/AT103/functions.php'; require '/home3/username/public_html/staging/wp-content/themes/AT103/functions.php';
但所有尝试都导致收不到邮件,推测这些代码有错误,用require_once()也得到同样结果。
- 如何在Cron Job中访问目录结构内其他脚本的“实时”变量或函数?
- 若无法实现,是否可以直接访问数据库信息?
针对问题1:加载WordPress核心环境实现变量与函数调用
你单独加载主题functions.php无效的核心原因是:WordPress的函数、变量(比如$post)依赖完整的WP核心环境初始化,单独加载主题文件无法触发这些机制。正确的做法是在test-cron.php开头加载WP根目录下的wp-load.php,以此初始化整个WP环境。
修改test-cron.php开头代码(替换为你服务器上实际的wp-load.php绝对路径):
require_once '/home3/username/public_html/staging/wp-load.php';
加载完成后,WP会自动加载主题的functions.php,你可以直接调用自定义函数,也能使用WP内置函数(比如get_posts())获取列表数据。举个实现逻辑的示例:
<?php require_once '/home3/username/public_html/staging/wp-load.php'; // 假设列表是自定义文章类型'listing',过期字段为'expiry_date' $expired_listings = get_posts([ 'post_type' => 'listing', 'post_status' => 'publish', 'meta_query' => [ [ 'key' => 'expiry_date', 'value' => current_time('timestamp'), 'compare' => '<', 'type' => 'NUMERIC' ] ] ]); foreach ($expired_listings as $listing) { // 获取买卖双方邮箱(假设对应自定义字段已存在) $seller_email = get_post_meta($listing->ID, 'seller_email', true); $buyer_email = get_post_meta($listing->ID, 'buyer_email', true); $subject = "你的商品列表已过期"; $message = "你发布的「{$listing->post_title}」已过期,请及时处理。"; if ($seller_email) wp_mail($seller_email, $subject, $message); if ($buyer_email) wp_mail($buyer_email, $subject, $message); } ?>
如果不确定绝对路径,可以在WP后台临时创建一个PHP文件,输出echo ABSPATH;来获取网站根目录路径,以此推导wp-load.php的位置。
针对问题2:直接访问数据库完全可行
如果不想加载WP环境,也可以通过PHP直接连接数据库查询数据。步骤如下:
- 从WP的
wp-config.php中复制数据库信息(DB_NAME、DB_USER、DB_PASSWORD、DB_HOST) - 用PHP的mysqli或PDO建立连接,编写SQL查询过期列表
- 遍历结果并发送邮件
示例代码:
<?php // 从wp-config.php复制的数据库配置 define('DB_NAME', '你的数据库名'); define('DB_USER', '数据库用户名'); define('DB_PASSWORD', '数据库密码'); define('DB_HOST', 'localhost'); // 建立数据库连接 $conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); if ($conn->connect_error) die("连接失败: " . $conn->connect_error); // 查询过期列表(假设列表存储在wp_posts,过期字段在wp_postmeta) $sql = " SELECT p.ID, p.post_title, pm_seller.meta_value AS seller_email, pm_buyer.meta_value AS buyer_email FROM wp_posts p JOIN wp_postmeta pm_expiry ON p.ID = pm_expiry.post_id AND pm_expiry.meta_key = 'expiry_date' LEFT JOIN wp_postmeta pm_seller ON p.ID = pm_seller.post_id AND pm_seller.meta_key = 'seller_email' LEFT JOIN wp_postmeta pm_buyer ON p.ID = pm_buyer.post_id AND pm_buyer.meta_key = 'buyer_email' WHERE p.post_type = 'listing' AND p.post_status = 'publish' AND pm_expiry.meta_value < UNIX_TIMESTAMP() "; $result = $conn->query($sql); if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { $subject = "你的商品列表已过期"; $message = "你发布的「{$row['post_title']}」已过期,请及时处理。"; if ($row['seller_email']) mail($row['seller_email'], $subject, $message); if ($row['buyer_email']) mail($row['buyer_email'], $subject, $message); } } $conn->close(); ?>
不过这种方式需要自行处理数据逻辑与安全校验,不如加载WP环境省心——WP已经封装了成熟的数据库操作和安全机制,优先推荐前者。
内容的提问来源于stack exchange,提问作者eligolf

