WordPress站点持续出现chmod/utime权限错误及WooCommerce FTP连接TypeError问题求助
问题描述
我负责维护一个客户的WordPress站点,之前在主题文件里加了一个cron.php用来执行定时任务,前阵子运行都没问题,但最近突然出状况了:
- 直接在服务器上执行这个文件时,抛出致命错误:
PHP Fatal error: Uncaught TypeError: ftp_nlist(): Argument #1 ($ftp) must be of type FTP\Connection, null given in wp-admin/includes/class-wp-filesystem-ftpext.php:438
追踪栈显示这个错误是WooCommerce的日志写入流程触发的,最终指向WP的FTP文件系统类。 - 后来我尝试了一些修复方案,暂时解决了问题,但过几个小时又会出现新的权限警告:
PHP Warning: touch(): Utime failed: Operation not permitted in wp-admin/includes/class-wp-filesystem-direct.php on line 529
PHP Warning: chmod(): Operation not permitted in wp-admin/includes/class-wp-filesystem-direct.php on line 173
重新设置权限和所有者后,问题会消失一段时间,但之后又会重复出现。另外我注意到WooCommerce官方已经把这个FTP连接的TypeError标记为一个bug。
已尝试的解决方案
我查了不少论坛和博客,做了这些操作:
- 在配置里添加
define('fs_method', 'direct'),强制WP使用直接文件系统而非FTP - 通过服务器命令调整站点文件的所有者和权限:
sudo chown -R www-data:www-data /path/to/wordpress find /path/to/wordpress -type d -exec chmod 755 {} \; find /path/to/wordpress -type f -exec chmod 644 {} \; chmod 775 /path/to/wordpress/wp-content/uploads/wc-logs
这些操作确实能让定时任务正常运行几个小时,但之后权限警告又会卷土重来,没法彻底解决。
我的cron.php代码(已屏蔽站点和第三方集成信息)
<?php ini_set('log_errors', 1); ini_set('error_log', '/path/to/your/logfile.log'); error_reporting(E_ALL); //ini_set('display_errors', 1); if (!defined('FS_METHOD') && php_sapi_name() === 'cli') { define('FS_METHOD', 'direct'); } include '/path/to/your/wp-config.php'; if (function_exists('add_filter')) { add_filter('woocommerce_logger_handlers', '__return_empty_array'); } //echo "reached here "; const HOST = DB_HOST; const USERNAME = DB_USER; const PASSWORD = DB_PASSWORD; const DATABASE = DB_NAME; $db = new mysqli(HOST, USERNAME, PASSWORD, DATABASE); if ($db->connect_error) { error_log("Database connection failed: " . $db->connect_error); die("Database connection failed: " . $db->connect_error); } require_once '/path/to/your/sdk/ServiceClient.php'; if (!class_exists('Masked\Class\AccountingInfo')) { echo 'AccountingInfo class not found.'; error_log('AccountingInfo class not found.'); } else { echo 'AccountingInfo class found and ready to use.<br>'; } $accountingInfo = new Masked\Class\AccountingInfo(); if (is_null($accountingInfo)) { echo 'Failed to create AccountingInfo object.'; error_log('Failed to create AccountingInfo object.'); } else { echo 'AccountingInfo object created successfully.<br>'; } function get_custom_field_after_checkout_cron($order_id) { $order = wc_get_order($order_id); foreach ($order->get_items() as $item_id => $item_data) { $product_id = $item_data->get_product_id(); $product_guid = get_post_meta($product_id, 'product_guid', true); } return $product_guid; } function get_custom_field_after_order_cron($order_id) { $order = wc_get_order($order_id); foreach ($order->get_items() as $item_id => $item_data) { $subscription_term_guid = $item_data->get_product_id(); $item_meta_data = $item_data->get_meta_data(); $guid_field = "day"; foreach ($item_meta_data as $meta) { if ($meta->key === 'subscription') { $duration = $subscription_values[$item_data->get_product_id()] = $meta->value; if ($duration == "Daily") { $guid_field = "day"; } else if ($duration == "Monthly") { $guid_field = "month"; } // 原代码此处逻辑未完成 } } } // 原代码此处返回逻辑缺失 }
求助需求
现在这个问题反复出现,常规的权限调整和fs_method设置只能临时解决,有没有更彻底的修复方案?比如是不是WooCommerce的日志机制有什么特殊的权限要求?或者我的cron.php里有没有什么需要调整的地方?希望能得到各位的经验分享和建议。
内容来源于stack exchange

