如何在PHP电商网站中集成Python图像分析功能?
解决PHP电商网站与Python图像分析服务的集成问题
核心问题分析
- 端口冲突:当前Python代码运行在8080端口,与PHP服务端口重复,无法同时运行
- Python服务设计偏差:原代码试图渲染PHP模板,应作为独立API服务提供图像分析结果
- PHP表单逻辑错误:图片上传的提交按钮位于表单外部,无法触发文件上传
解决方案步骤
1. 重构Python服务为REST API
修改Python代码,使其以API形式返回JSON格式的分析结果,运行在127.0.0.1:5000:
import os from flask import Flask, request, jsonify import numpy as np from tensorflow.keras.preprocessing.image import load_img, img_to_array from keras.applications.resnet_v2 import preprocess_input as resnet152v2_preprocess_input from keras.applications.resnet_v2 import ResNet152V2 from keras.applications.imagenet_utils import decode_predictions model = ResNet152V2(weights='imagenet') class_dict = { 'notebook': 'laptop', 'cellular_telephone': 'Smartphone', 'hand-held_computer': 'Smartphone', 'remote_control': 'Smartphone', 'iPod': 'Smartphone', 'microphone': 'Headphone', 'espresso_maker': 'Headphone', 'washer': 'Washing Machine', 'analog_clock': 'Watch', 'digital_watch': 'Watch', 'reflex_camera': 'Camera', 'vending_machine': 'Fridge', 'pill_bottle': 'Water Bottle', 'water_bottle': 'Water Bottle', 'ashcan': 'Fridge' } app = Flask(__name__) UPLOAD_FOLDER = 'uploads' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER os.makedirs(UPLOAD_FOLDER, exist_ok=True) # 确保上传目录存在 ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} app.config['ALLOWED_EXTENSIONS'] = ALLOWED_EXTENSIONS def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS'] @app.route('/analyze-image', methods=['POST']) def analyze_image(): if 'file' not in request.files: return jsonify({'error': 'No file selected'}), 400 file = request.files['file'] if not allowed_file(file.filename): return jsonify({'error': 'File type not allowed'}), 400 filename = file.filename file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(file_path) # 图像预处理与预测 img = load_img(file_path, target_size=(224, 224)) img = img_to_array(img) img = np.expand_dims(img, axis=0) img = resnet152v2_preprocess_input(img) preds = model.predict(img) decoded_preds = decode_predictions(preds, top=1)[0] # 映射分类名称 pred = decoded_preds[0] mapped_label = class_dict.get(pred[1], pred[1]) probability = float(pred[2]) # 删除临时文件(可选,避免存储冗余) os.remove(file_path) return jsonify({ 'keyword': mapped_label, 'probability': probability }) if __name__ == '__main__': app.run(debug=True, port=5000)
2. 修改PHP代码,实现表单上传与API调用
调整PHP图片上传表单,提交后调用Python API获取关键词,再执行商品搜索:
<?php include 'components/connect.php'; session_start(); $user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : ''; $image_result = ''; $search_keyword = ''; // 处理图片上传与API调用 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) { $file = $_FILES['file']; // 验证文件 $allowed_ext = ['png', 'jpg', 'jpeg', 'gif']; $file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($file_ext, $allowed_ext)) { $image_result = '<p class="empty">文件类型不允许!</p>'; } elseif ($file['error'] !== UPLOAD_ERR_OK) { $image_result = '<p class="empty">文件上传失败!</p>'; } else { // 调用Python API $api_url = 'http://127.0.0.1:5000/analyze-image'; $curl = curl_init(); $post_data = [ 'file' => new CURLFile($file['tmp_name'], $file['type'], $file['name']) ]; curl_setopt($curl, CURLOPT_URL, $api_url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($http_code === 200) { $result = json_decode($response, true); $search_keyword = $result['keyword']; $image_result = '<p>识别结果:' . $result['keyword'] . ',置信度:' . number_format($result['probability']*100, 2) . '%</p>'; } else { $error = json_decode($response, true)['error'] ?? 'API调用失败'; $image_result = '<p class="empty">' . $error . '</p>'; } } } // 处理关键词搜索 $products = []; if (isset($_POST['search_box']) || !empty($search_keyword)) { $search_box = !empty($search_keyword) ? $search_keyword : $_POST['search_box']; $select_products = $conn->prepare("SELECT * FROM `products` WHERE name LIKE ?"); $select_products->execute(['%' . $search_box . '%']); $products = $select_products->fetchAll(PDO::FETCH_ASSOC); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>search page</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"> <link rel="stylesheet" href="css/style.css"> </head> <body> <?php include 'components/user_header.php'; ?> <section class="search-form"> <form action="" method="post"> <input type="text" name="search_box" placeholder="search here..." maxlength="100" class="box" value="<?= htmlspecialchars($search_keyword) ?>" required> <button type="submit" class="fas fa-search" name="search_btn"></button> </form> </section> <section class="search-form"> <form method="POST" enctype="multipart/form-data"> <input type="file" name="file" id="file" accept="image/*"> <br><br> <button type="button" onclick="previewImage()">预览</button> <br><br> <img src="" id="imgPreview" style="display:none;max-width:300px;max-height:300px;"> <br><br> <button type="submit" value="上传识别" class="btn">上传识别</button> </form> <?= $image_result ?> <script type="text/javascript"> function previewImage() { var preview = document.getElementById("imgPreview"); var file = document.getElementById("file").files[0]; var reader = new FileReader(); reader.onloadend = function () { preview.src = reader.result; preview.style.display = "block"; } if (file) { reader.readAsDataURL(file); } else { preview.src = ""; preview.style.display = "none"; } } </script> </section> <section class="products" style="padding-top: 0; min-height:100vh;"> <div class="box-container"> <?php if (!empty($products)): ?> <?php foreach ($products as $fetch_product): ?> <form action="" method="post" class="box"> <input type="hidden" name="pid" value="<?= $fetch_product['id']; ?>"> <input type="hidden" name="name" value="<?= $fetch_product['name']; ?>"> <input type="hidden" name="price" value="<?= $fetch_product['price']; ?>"> <input type="hidden" name="image" value="<?= $fetch_product['image_01']; ?>"> <a href="quick_view.php?pid=<?= $fetch_product['id']; ?>" class="fas fa-eye"></a> <img src="uploaded_img/<?= $fetch_product['image_01']; ?>" alt=""> <div class="name"><?= $fetch_product['name']; ?></div> <div class="flex"> <div class="price"><span>Rs. </span><?= $fetch_product['price']; ?><span>/-</span></div> <input type="number" name="qty" class="qty" min="1" max="99" onkeypress="if(this.value.length == 2) return false;" value="1"> </div> <input type="submit" value="add to cart" class="btn" name="add_to_cart"> </form> <?php endforeach; ?> <?php else: ?> <p class="empty">no products found!</p> <?php endif; ?> </div> </section> <?php include 'components/footer.php'; ?> <script src="js/script.js"></script> </body> </html>
关键修改说明
- Python端:
- 路由改为
/analyze-image,返回JSON结果而非渲染模板 - 自动创建上传目录,可选删除临时文件避免存储冗余
- 端口改为5000,避免与PHP服务冲突
- 路由改为
- PHP端:
- 修复表单结构,将提交按钮移至表单内部
- 使用cURL调用Python API,传递上传文件
- 将识别出的关键词自动填入搜索框并执行商品搜索
- 增加错误处理,展示识别结果或错误信息
运行步骤
- 启动Python服务:运行修改后的Python脚本,确认服务在127.0.0.1:5000正常运行
- 启动PHP服务:确保PHP服务在localhost:8080正常运行
- 访问PHP网站的搜索页面,上传图片即可自动识别关键词并搜索对应商品
内容的提问来源于stack exchange,提问作者Yash Kumar
相关产品推荐
相关产品推荐

