
本教程详细介绍了如何将react.js前端与php后端通过restful api进行连接。文章将涵盖后端api的构建、前端数据请求与处理,以及跨域资源共享(cors)等关键配置,旨在帮助开发者高效地构建全栈web应用。
在现代Web开发中,前端与后端分离已成为主流实践。React.js作为流行的前端库,负责构建用户界面;而PHP则常用于处理服务器端逻辑、数据库交互和API服务。通过RESTful API,两者可以无缝协作,共同构建功能强大的Web应用程序。
理解React.js与PHP的协作模式
React.js应用通常运行在用户的浏览器中,负责渲染UI和响应用户操作。它通过HTTP请求(如GET、POST、PUT、DELETE)与后端API进行通信,获取或提交数据。PHP后端则接收这些请求,处理业务逻辑,与数据库交互,并以JSON等格式返回数据给前端。这种模式的核心是RESTful API,它定义了一套标准化的接口,使得不同技术栈的组件能够互相理解和通信。
构建PHP后端API
为了将原始的PHP CLI脚本转换为可供React.js调用的Web API,我们需要进行以下改造:
接收HTTP请求参数:将CLI参数($_SERVER[‘argv’])替换为HTTP请求参数(如$_GET或$_POST)。输出JSON数据:将纯文本输出改为JSON格式,并设置正确的Content-Type头。处理HTTP方法:虽然本示例主要使用GET请求,但在实际应用中,后端应能根据HTTP方法(GET、POST、PUT、DELETE)执行不同的操作。
假设我们有一个data.json文件作为数据源:
立即学习“PHP免费学习笔记(深入)”;
[ { "offerId": 1, "productTitle": "Laptop", "vendorId": 101, "price": 1200 }, { "offerId": 2, "productTitle": "Mouse", "vendorId": 101, "price": 25 }, { "offerId": 3, "productTitle": "Keyboard", "vendorId": 102, "price": 75 }, { "offerId": 4, "productTitle": "Monitor", "vendorId": 103, "price": 300 }, { "offerId": 5, "productTitle": "Webcam", "vendorId": 102, "price": 50 }, { "offerId": 6, "productTitle": "Headphones", "vendorId": 101, "price": 150 }]
我们将原有的PHP代码封装为一个API入口文件 api.php:
offerId | $this->productTitle | $this->vendorId | $this->pricen"; }}class OfferCollection implements OfferCollectionInterface{ private $offersList = array(); public function __construct($data) { if (is_array($data)) { foreach ($data as $json_object) { $offer = new Offer(); $offer->offerId = $json_object->offerId; $offer->productTitle = $json_object->productTitle; $offer->vendorId = $json_object->vendorId; $offer->price = $json_object->price; array_push($this->offersList, $offer); } } } public function get(int $index): OfferInterface { return $this->offersList[$index]; } public function getIterator(): Iterator { return new ArrayIterator($this->offersList); } public function __toString(): string { return implode("n", $this->offersList); } // 新增方法:将OfferCollection转换为数组,以便json_encode public function toArray(): array { $result = []; foreach ($this->offersList as $offer) { $result[] = [ 'offerId' => $offer->offerId, 'productTitle' => $offer->productTitle, 'vendorId' => $offer->vendorId, 'price' => $offer->price, ]; } return $result; }}class Reader implements ReaderInterface{ /** * Read in incoming data and parse to objects */ public function read(string $input): OfferCollectionInterface { if ($input != null) { $content = file_get_contents($input); $json = json_decode($content); $result = new OfferCollection($json); return $result; } return new OfferCollection(null); }}class Logger{ private $filename = "logs.txt"; public function info($message): void { $this->log($message, "INFO"); } public function error($message): void { $this->log($message, "ERROR"); } private function log($message, $type): void { $myfile = fopen($this->filename, "a") or die("Unable to open file!"); $txt = "[$type] $messagen"; fwrite($myfile, $txt); fclose($myfile); }}$json_url = 'data.json';$json_reader = new Reader();$offers_list = $json_reader->read($json_url);function count_by_price_range($price_from, $price_to){ global $offers_list; $count = 0; foreach ($offers_list->getIterator() as $offer) { if ($offer->price >= $price_from && $offer->price getIterator() as $offer) { if ($offer->vendorId == $vendorId) { $count++; } } return $count;}// 获取请求路径和参数$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);$path_segments = explode('/', trim($request_uri, '/'));$api_endpoint = end($path_segments); // 假设API路径的最后一段是功能名称$logger = new Logger();$response_data = [];$status_code = 200;switch ($api_endpoint) { case "count_by_price_range": { $price_from = $_GET['from'] ?? null; $price_to = $_GET['to'] ?? null; if ($price_from !== null && $price_to !== null) { $logger->info("Getting Count By Price Range From: $price_from TO $price_to"); $response_data = ['count' => count_by_price_range((float)$price_from, (float)$price_to)]; } else { $status_code = 400; $response_data = ['error' => 'Missing price range parameters (from, to).']; } break; } case "count_by_vendor_id": { $vendorId = $_GET['vendorId'] ?? null; if ($vendorId !== null) { $logger->info("Getting Count By vendor Id: $vendorId"); $response_data = ['count' => count_by_vendor_id((int)$vendorId)]; } else { $status_code = 400; $response_data = ['error' => 'Missing vendorId parameter.']; } break; } case "offers": { // 新增一个获取所有offer的接口 $response_data = ['offers' => $offers_list->toArray()]; break; } default: { $status_code = 404; $response_data = ['error' => 'API endpoint not found.']; break; }}http_response_code($status_code);echo json_encode($response_data);?>
将 api.php 和 data.json 放在一个支持PHP的Web服务器(如Apache或Nginx)的根目录下。现在,你可以通过访问类似 http://localhost/api.php/count_by_price_range?from=50&to=200 或 http://localhost/api.php/offers 来测试API。
创建React.js前端应用
接下来,我们创建一个简单的React组件来调用这个PHP API并显示数据。
初始化React项目如果你还没有React项目,可以使用Create React App快速搭建:
npx create-react-app react-php-appcd react-php-appnpm start
编写React组件修改 src/App.js 文件,添加一个组件来获取并展示数据:
import React, { useState, useEffect } from 'react';import './App.css';function App() { const [offers, setOffers] = useState([]); const [priceRangeCount, setPriceRangeCount] = useState(0); const [vendorIdCount, setVendorIdCount] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // PHP API 的基础URL,请根据你的实际部署修改 const API_BASE_URL = 'http://localhost/api.php'; useEffect(() => { const fetchData = async () => { try { // 获取所有Offers const offersResponse = await fetch(`${API_BASE_URL}/offers`); if (!offersResponse.ok) { throw new Error(`HTTP error! status: ${offersResponse.status}`); } const offersData = await offersResponse.json(); setOffers(offersData.offers || []); // 获取价格区间统计 const priceRangeResponse = await fetch(`${API_BASE_URL}/count_by_price_range?from=50&to=200`); if (!priceRangeResponse.ok) { throw new Error(`HTTP error! status: ${priceRangeResponse.status}`); } const priceRangeData = await priceRangeResponse.json(); setPriceRangeCount(priceRangeData.count || 0); // 获取供应商ID统计 const vendorIdResponse = await fetch(`${API_BASE_URL}/count_by_vendor_id?vendorId=101`); if (!vendorIdResponse.ok) { throw new Error(`HTTP error! status: ${vendorIdResponse.status}`); } const vendorIdData = await vendorIdResponse.json(); setVendorIdCount(vendorIdData.count || 0); } catch (error) { console.error("Error fetching data:", error); setError(error); } finally { setLoading(false); } }; fetchData(); }, []); // 空数组表示只在组件挂载时运行一次 if (loading) return Loading data...; if (error) return Error: {error.message}; return ( React.js & PHP API 集成示例
所有商品列表
{offers.length > 0 ? ( {offers.map(offer => ( - ID: {offer.offerId}, Title: {offer.productTitle}, Vendor: {offer.vendorId}, Price: ${offer.price}
))}
) : ( 没有商品数据。
)} 统计信息
价格在 $50 到 $200 之间的商品数量: {priceRangeCount}
供应商ID为 101 的商品数量: {vendorIdCount}
);}export default App;
处理跨域资源共享 (CORS)
在开发阶段,React应用通常运行在 http://localhost:3000,而PHP后端可能运行在 http://localhost 或 http://localhost:80。由于它们端口或域名不同,浏览器会阻止React应用直接访问PHP API,这就是所谓的“跨域”问题。
为了解决这个问题,PHP后端需要发送特定的HTTP响应头,告知浏览器允许来自React应用源的请求。在 api.php 的开头,我们已经添加了以下CORS头:
header("Access-Control-Allow-Origin: http://localhost:3000"); // 允许来自React开发服务器的请求header("Content-Type: application/json; charset=UTF-8");header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // 允许的HTTP方法header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");// 处理OPTIONS请求,用于CORS预检if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit();}
Access-Control-Allow-Origin: 指定允许访问资源的源。在生产环境中,应将其设置为你的前端域名,或者根据需要动态设置。* 可以允许所有源,但出于安全考虑,不建议在生产环境中使用。Access-Control-Allow-Methods: 指定允许的HTTP方法。Access-Control-Allow-Headers: 指定在实际请求中可以使用的HTTP头。当浏览器发送跨域请求时,对于某些复杂的请求(如带有自定义头或非简单方法的请求),会先发送一个OPTIONS请求(预检请求)。后端需要正确响应这个OPTIONS请求。
部署与注意事项
生产环境CORS配置:在生产环境中,Access-Control-Allow-Origin 应精确设置为你的前端应用的域名(例如 https://your-react-app.com),而不是 http://localhost:3000 或 *。API路由:对于更复杂的应用,建议使用一个成熟的PHP框架(如Laravel、Symfony)来处理路由、请求验证和ORM,这会使API开发更加高效和健壮。安全性:输入验证:始终验证来自前端的所有输入,防止SQL注入、XSS等攻击。认证与授权:实现用户认证(如JWT、Session)和授权机制,确保只有经过身份验证的用户才能访问受保护的API资源。HTTPS:在生产环境中,始终使用HTTPS来加密前后端之间的通信。错误处理:后端API应提供清晰的错误响应(如HTTP状态码和JSON格式的错误信息),前端也应妥善处理这些错误并向用户展示友好的提示。性能优化:对于数据量大的API,考虑分页、缓存、数据库索引等优化措施。
总结
通过RESTful API,React.js和PHP可以高效地协同工作,分别专注于前端的用户体验和后端的业务逻辑。构建一个稳健的API涉及请求处理、数据格式化、CORS配置以及安全性考量。遵循本教程的指导,开发者可以顺利地将React.js前端与PHP后端集成,构建出功能完善、结构清晰的Web应用程序。
以上就是React.js与PHP后端集成:构建RESTful API应用教程的详细内容,更多请关注php中文网其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1324455.html
微信扫一扫
支付宝扫一扫