外部链接自动转联盟链接的代码失效问题排查
问题描述
我需要在产品数据解析完成后,自动为来自example.com或其他广告主的产品URL添加联盟链接。我已在以下代码中实现相关逻辑:检测产品URL是否包含example.com,若是则生成追踪链接,并注册用于联盟链接转换的JavaScript脚本,但目前联盟链接并未成功转换,恳请协助排查问题。
<?php namespace ExternalImporter\application\libs\pextractor\parser\parsers; use ExternalImporter\application\libs\pextractor\parser\AdvancedParser; use ExternalImporter\application\libs\pextractor\parser\Product; class ExampleAdvanced extends AdvancedParser { public function getHttpOptions() { $user_agent = array('ia_archiver'); return array('user-agent' => $user_agent[array_rand($user_agent)]); } public function parseLinks() { $path = array( ".//a[@class='product__title a']/@href", ); return $this->xpathArray($path); } public function parseTitle() { return $this->xpathScalar(".//h1[@class='product__title']") . ' ' . $this->xpathScalar(".//h2[@class='product-details__description inherit-font-styles']"); } public function parseDescription() { $d = $this->xpathScalar(".//div[@id='tab6']", true); return preg_replace('~<div class="product-number text-uppercase">.+?</div>~ims', '', $d); } public function afterParseFix(Product $product) { // Replace image URLs $product->image = str_replace(',w_520,h_520,', ',w_1800,h_1800,', $product->image); foreach ($product->images as $k => $img) { $product->images[$k] = str_replace(',w_520,h_520,', ',w_1800,h_1800,', $img); } // Import images to the WooCommerce product gallery $this->importImageToProductGallery($product->id, $product->image); foreach ($product->images as $img) { $this->importImageToProductGallery($product->id, $img); } // Update the product URL to the affiliate link only for example.com if (strpos($product->url, 'example.com') !== false) { $product->url = $this->generateTrackingLink($product->url); // Enqueue the JavaScript for affiliate link conversion add_action('wp_footer', function () use ($product) { $this->addAffiliateJavascript($product->url); }); } return $product; } protected function importImageToProductGallery($productId, $imageUrl) { // Download the image to a temporary file (use wp_remote_get for WordPress) $response = wp_remote_get($imageUrl); $tempFilePath = wp_tempnam($imageUrl); if (is_wp_error($response) || !is_wp_error($tempFilePath)) { // Handle the error, log it, etc. return; } // Get the file name from the URL $filename = basename($imageUrl); // Prepare the image data for WooCommerce $imageData = [ 'name' => $filename, 'post_title' => $filename, 'post_content' => '', 'post_status' => 'inherit', ]; // Create an attachment from the temporary file and add it to the product gallery $attachmentId = wp_insert_attachment($imageData, $tempFilePath, $productId); if (!is_wp_error($attachmentId)) { require_once(ABSPATH . 'wp-admin/includes/image.php'); $attachmentData = wp_generate_attachment_metadata($attachmentId, $tempFilePath); wp_update_attachment_metadata($attachmentId, $attachmentData); // Add the image to the product gallery add_post_meta($productId, '_product_image_gallery', $attachmentId, false); } // Clean up the temporary file unlink($tempFilePath); // Add any additional processing or linking logic as needed } protected function addAffiliateJavascript($productUrl) { ?> <script> jQuery(document).ready(function($) { // Attach a click event to all <a> elements $("a").click(function() { // Check if the link is from example.com if ($(this).attr('href').indexOf('example.com') >= 0) { // Check if the link already contains the affiliate parameters if ($(this).attr('href').indexOf('id=a0s*vOA3SnI') < 0) { // Update the link with the affiliate parameters $(this).attr('href', function(_, currentHref) { return currentHref + (currentHref.includes('?') ? '&' : '?') + 'id=a0s*vOA3SnI&mid=50238&murl=' + encodeURIComponent(currentHref); }); } } // Return true to follow the link return true; }); }); </script> <?php } }
问题排查与修复方案
核心问题拆解
你的代码存在多个逻辑漏洞,直接导致联盟链接转换失败:
- PHP端核心方法缺失:调用了
generateTrackingLink但未实现,PHP层面无法生成有效追踪链接 - JS事件绑定失效:
ready绑定的点击事件无法覆盖动态加载的链接(比如WooCommerce后期渲染的按钮) - URL判断逻辑粗糙:直接用
attr('href')可能获取不到有效路径,indexOf判断容易遗漏相对路径、跨域链接 - 钩子重复注册:每次解析产品都会添加
wp_footer钩子,导致页面加载多份相同JS,引发冲突 - 图片导入逻辑错误:
wp_remote_get结果判断颠倒,未将下载内容写入临时文件,图库追加逻辑会覆盖原有图片
修复后的完整代码
<?php namespace ExternalImporter\application\libs\pextractor\parser\parsers; use ExternalImporter\application\libs\pextractor\parser\AdvancedParser; use ExternalImporter\application\libs\pextractor\parser\Product; class ExampleAdvanced extends AdvancedParser { public function getHttpOptions() { $user_agent = array('ia_archiver'); return array('user-agent' => $user_agent[array_rand($user_agent)]); } public function parseLinks() { $path = array( ".//a[@class='product__title a']/@href", ); return $this->xpathArray($path); } public function parseTitle() { return $this->xpathScalar(".//h1[@class='product__title']") . ' ' . $this->xpathScalar(".//h2[@class='product-details__description inherit-font-styles']"); } public function parseDescription() { $d = $this->xpathScalar(".//div[@id='tab6']", true); return preg_replace('~<div class="product-number text-uppercase">.+?</div>~ims', '', $d); } public function afterParseFix(Product $product) { // 替换图片URL尺寸 $product->image = str_replace(',w_520,h_520,', ',w_1800,h_1800,', $product->image); foreach ($product->images as $k => $img) { $product->images[$k] = str_replace(',w_520,h_520,', ',w_1800,h_1800,', $img); } // 导入图片到WooCommerce产品图库 $this->importImageToProductGallery($product->id, $product->image); foreach ($product->images as $img) { $this->importImageToProductGallery($product->id, $img); } // 仅为example.com的产品URL生成联盟链接 if (strpos($product->url, 'example.com') !== false) { $product->url = $this->generateTrackingLink($product->url); } // 全局注册一次JS转换脚本(避免重复注册) if (!has_action('wp_footer', [$this, 'addAffiliateJavascript'])) { add_action('wp_footer', [$this, 'addAffiliateJavascript']); } return $product; } // 实现缺失的联盟链接生成方法 protected function generateTrackingLink($originalUrl) { $affiliateParams = [ 'id' => 'a0s*vOA3SnI', 'mid' => '50238', 'murl' => urlencode($originalUrl) ]; $separator = strpos($originalUrl, '?') !== false ? '&' : '?'; return $originalUrl . $separator . http_build_query($affiliateParams); } protected function importImageToProductGallery($productId, $imageUrl) { // 下载图片到临时文件 $response = wp_remote_get($imageUrl); if (is_wp_error($response)) { return; } $tempFilePath = wp_tempnam($imageUrl); if (is_wp_error($tempFilePath)) { return; } // 将下载的内容写入临时文件 file_put_contents($tempFilePath, wp_remote_retrieve_body($response)); // 获取文件名 $filename = basename($imageUrl); // 准备图片附件数据 $imageData = [ 'name' => $filename, 'post_title' => $filename, 'post_content' => '', 'post_status' => 'inherit', ]; // 创建附件并添加到产品图库 $attachmentId = wp_insert_attachment($imageData, $tempFilePath, $productId); if (!is_wp_error($attachmentId)) { require_once(ABSPATH . 'wp-admin/includes/image.php'); $attachmentData = wp_generate_attachment_metadata($attachmentId, $tempFilePath); wp_update_attachment_metadata($attachmentId, $attachmentData); // 追加到产品图库(避免覆盖原有图库) $existingGallery = get_post_meta($productId, '_product_image_gallery', true); $newGallery = $existingGallery ? $existingGallery . ',' . $attachmentId : $attachmentId; update_post_meta($productId, '_product_image_gallery', $newGallery); } // 清理临时文件 unlink($tempFilePath); } protected function addAffiliateJavascript() { ?> <script> jQuery(document).on('click', 'a', function(e) { let href = $(this).attr('href'); if (!href) return true; // 处理相对路径转为绝对URL let urlObj = new URL(href, window.location.origin); let fullUrl = urlObj.href; // 检查是否为example.com链接且未包含联盟参数 if (fullUrl.includes('example.com') && !fullUrl.includes('id=a0s*vOA3SnI')) { // 生成联盟链接 let separator = fullUrl.includes('?') ? '&' : '?'; let affiliateParams = 'id=a0s*vOA3SnI&mid=50238&murl=' + encodeURIComponent(fullUrl); $(this).attr('href', fullUrl + separator + affiliateParams); } return true; }); </script> <?php } }
关键修复说明
- 补全
generateTrackingLink方法:PHP端直接生成正确的联盟链接,确保产品初始URL就是追踪链接 - 优化JS事件绑定:改用事件委托
jQuery(document).on('click', 'a', ...),覆盖所有动态生成的链接 - 完善URL处理:使用
URL对象解析链接,解决相对路径、跨域链接的判断问题 - 避免重复注册钩子:通过
has_action判断,确保JS脚本只加载一次 - 修复图片导入逻辑:修正
wp_remote_get结果判断,添加文件写入步骤,优化图库追加逻辑避免覆盖原有图片
内容的提问来源于stack exchange,提问作者Huda
相关产品推荐
相关产品推荐

