求助:PHP调用Shopify API获取全量商品并输出至页面
Hey there! Great job getting your Shopify API connection and MySQL inserts up and running—you're already halfway there. Let's fix that "only 250 products at a time" problem, since Shopify's API pagination is the key here.
How Shopify's Pagination Works
Shopify uses cursor-based pagination for most of its REST API endpoints (it's more efficient than offset-based pagination and avoids data gaps when products are added/removed mid-fetch). Here's the gist:
- Each request returns up to 250 items (the max
limitvalue allowed). - The response includes a
Linkheader with a URL for the next page of results (if there are more products). - You'll keep looping through these next-page URLs until there are no more products to fetch.
Step-by-Step Implementation
Let's break this down with a practical example (using Python, but the logic translates to any language):
Initial Request
Start with a request to the products endpoint, settinglimit=250to get the maximum number of items per call.Check for Next Page
After each request, parse theLinkheader in the response to find the URL labeledrel="next". If this exists, there are more products to fetch.Loop Until All Products Are Fetched
Keep making requests to the next-page URL until theLinkheader no longer includes a "next" entry.
Example Code
import requests import mysql.connector import time # Replace these with your own values SHOPIFY_SHOP = "your-shop-name.myshopify.com" API_KEY = "your-api-key" API_SECRET = "your-api-secret" API_VERSION = "2024-07" # Use the latest stable API version # Initialize MySQL connection (your existing logic) db = mysql.connector.connect( host="your-db-host", user="your-db-user", password="your-db-password", database="your-db-name" ) cursor = db.cursor() def get_all_shopify_products(): all_products = [] next_page = f"https://{SHOPIFY_SHOP}/admin/api/{API_VERSION}/products.json?limit=250" while next_page: try: response = requests.get(next_page, auth=(API_KEY, API_SECRET)) response.raise_for_status() # Throw error for HTTP status codes >=400 data = response.json() all_products.extend(data["products"]) # Extract next page URL from Link header next_page = None link_header = response.headers.get("Link") if link_header: for link in link_header.split(","): if 'rel="next"' in link: next_page = link.split(";")[0].strip("<>") # Add a small delay to avoid hitting rate limits time.sleep(0.5) except requests.exceptions.RequestException as e: print(f"Request failed: {e}") break return all_products # Fetch all products products = get_all_shopify_products() print(f"Successfully fetched {len(products)} products!") # Insert/update products in MySQL (your existing logic, with upsert example) for product in products: upsert_query = """ INSERT INTO products (shopify_id, title, vendor, updated_at) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE title=%s, vendor=%s, updated_at=%s """ values = ( product["id"], product["title"], product["vendor"], product["updated_at"], product["title"], product["vendor"], product["updated_at"] ) cursor.execute(upsert_query, values) db.commit() cursor.close() db.close()
Key Tips to Avoid Headaches
- Use the Latest API Version: Shopify deprecates old versions regularly, so always stick to the current stable version to avoid broken functionality.
- Handle Rate Limits: Shopify allows 2 requests per second (with a burst of 40). Add a small delay between requests (like 0.5 seconds) or implement retry logic for 429 "Too Many Requests" errors.
- Incremental Updates: For future syncs, use the
updated_at_minparameter to only fetch products modified after your last sync (e.g.,?limit=250&updated_at_min=2024-01-01T00:00:00Z). This cuts down on unnecessary requests. - Error Handling: Add try/except blocks to catch network issues, API errors, or database failures—don't let a single failed request break your entire sync.
内容的提问来源于stack exchange,提问作者SimmiS

