在进行Web应用程序开发的时候,人们经常会用Session存储数据。但可能有人不知道,在PHP中,Session使用不当可能会引起并发问题。印度医疗行业软件解决方案提供商Plus91 Technologies高级工程师Kishan Gor在个人博客上对这个问题进行了阐释。 如果同一个客户端并发发送多个请求,而每个请求都使用了Session,那么PHP Session锁的存在会导致服务器串行响应这些请求,而不是并行。这是因为在默认情况下,PHP使用文件存储Session数据。对于每一个新的 Session,PHP会创建一个文件,并持续向其中写入数据。所以,每次调用session_start()方法,就会打开Session文件,并取得 文件的独占锁。这样,如果服务器脚本正在处理一个请求,而客户端又发送了一个同样需要使用Session的请求,那么后一个请求会阻塞,直至前一个请求处 理完成释放了文件上的独占锁。不过,这只限于来自同一个客户端的多个请求,也就是说,来自一个客户端的请求并不会阻塞另一个客户端的请求。 如果脚本很短,这通常没有问题。但如果脚本运行时间比较长,那就可能会产生问题。在现代Web应用程序开发中,有一个非常常见的情况,就是使用…
React搭配PHP的使用方法, PHP 和 React.js一起使用, An advanced guide on how to setup a React and PHP

A quick guide on setting up a React and PHP web. I love React and I still use PHP
在本文中,我将引导您为React Application设置PHP后端服务器。
要下载或浏览代码,请通过Github链接访问存储库。
通过此设置,您将能够在普通的Apache localhost而不是node js localhost:3000上运行和开发React应用,当您在开发Web应用时不想通过PHP或使用安全cookie强制进行身份验证重定向时,这很疯狂。或在应用程序启动前用PHP渲染一些东西。我还将添加SCSS支持和不错的高级功能。
好吧,现在让我们开始吧!
要求:您需要在本地计算机上安装Node.js和npm。以及XAMPP,WAMP或任何其他Web服务器解决方案。
设置文件夹结构
这是尘埃落定后我们将剩下的文件夹结构:

首先,我们现在需要创建php-react-app
根目录。这将保存我们所有的文件。接下来,app
将拥有包含整个React应用程序的文件夹。我添加了一个额外的文件夹_devapp
来托管我的React应用程序代码。如果服务器后端未在Node js上运行,我也建议您也这样做。还有一个assets
文件夹,其中包含我们编译的react和css。该node_modules
文件夹是不言自明的,但是它将包含我们app.js
文件的所有NPM软件包。当我们安装NPM时,它将自动创建。
后端入门
创建一个名为的新文件index.php
。
<?php $user = (object) [ 'name' => 'Jane Doe', 'email' => 'janedoe@gmail.com', 'logged' => true ]; ?> <!doctype html> <html lang="en"> <head> <title>React PHP starter Kit</title> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/app/assets/css/app.css" type="text/css"> </head> <script type="text/javascript"> var myApp = { user : <?php echo json_encode($user); ?>, logged : <?php echo $user->logged; ?> }; </script> <body> <div id="app"></div> <script type="text/javascript" src="/app/assets/bundle/main.bundle.js" ></script> </body> </html>
我们通过在index.php
文件中添加此javascript行来访问React应用。
<script type=”text/javascript” src=”/app/assets/bundle/main.bundle.js” ></script>
设置一个React应用
现在我们已经创建了index.php文件,让我们创建应用程序的前端。在我们的index.php文件所在的位置创建一个新目录,并将其命名为app。在我们的新终端中打开您的终端并输入,
npm init
在我们的应用目录中,找到package.json
文件。向其添加以下配置。
{ "name": "react-php", "version": "1.0.0", "description": "Setting up php and react web app", "main": "index.js", "scripts": { "build": "webpack --progress --env.NODE_ENV=production --mode production", "watch": "webpack --colors --debug --display-chunk -w --env.NODE_ENV=development --mode development" }, "dependencies": { "@babel/plugin-proposal-class-properties": "^7.2.3", "@babel/preset-react": "^7.0.0", "react": "^16.7.0", "react-async-component": "^2.0.0", "react-dom": "^16.7.0", "react-helmet": "^5.2.0", "react-hot-loader": "^4.6.3", "react-router-dom": "^4.3.1" }, "devDependencies": { "@babel/core": "^7.0.0-rc.1", "@babel/plugin-proposal-decorators": "^7.2.3", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "^7.0.0-rc.1", "@babel/preset-typescript": "^7.1.0", "autoprefixer": "^9.4.4", "babel-loader": "^8.0.0-beta.4", "css-loader": "^2.1.0", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^3.0.1", "node-sass": "^4.11.0", "path": "^0.12.7", "postcss-flexibility": "^2.0.0", "postcss-loader": "^3.0.0", "sass-loader": "^6.0.7", "style-loader": "^0.23.1", "webpack": "^4.17.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.14" }, "author": "I am a Pro", "license": "ISC" }
重要注意事项
我们正在将webpack配置为使用app.js
(具有我们的react javascript)和app.scss
(具有我们的应用程序css / style)作为我们的主要/入口文件。
entry: { main: [ ‘./_devapp/app.js’, ‘./_devapp/css/app.scss’ ] },
我们正在定义已编译脚本(assets/bundle
文件夹)的输出。
output: { path: path.resolve(__dirname, ‘assets’, ‘bundle’), filename: ‘[name].bundle.js’ },
由于某些原因,我没有将捆绑的css和js文件混合在一个文件夹中,而上面的代码就是这种情况,因此我在webpack.config.js
文件中添加了以下脚本。
plugins: [ new ExtractTextPlugin(path.join(‘..’, ‘css’, ‘app.css’)) ]
在我们的应用程序中,我们将MyApp全局变量导入到我们的react JS应用程序中。
这可以保持我们的应用程序清洁。window
除非有必要,否则避免从全局变量中导入变量。
externals: { myApp: ‘myApp’, },
最后,如果您的react应用正在连接到api,则最好通过webpack或应用将使用的api版本等其他静态变量来传递静态端点
plugins: [ new webpack.DefinePlugin({ ‘__DEV__’ : JSON.stringify(true), ‘__API_HOST__’ : JSON.stringify(‘http://localhost/my-app/'), }), ],
为了捆绑/编译我们的SCSS和React应用程序,我们将使用webpack。将以下内容复制到webpack.config.js文件中
'use strict'; const webpack = require('webpack'); const path = require('path'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); let config = { entry: { main: [ './_devapp/app.js', './_devapp/css/app.scss' ] }, output: { path: path.resolve(__dirname, 'assets', 'bundle'), filename: '[name].bundle.js' }, resolve: { extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'] }, module: { rules: [ { test: /\.(js|jsx|tsx|ts)$/, exclude:path.resolve(__dirname, 'node_modules'), use: { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript' ], plugins : [ ["@babel/plugin-proposal-decorators", { "legacy": true }], '@babel/plugin-syntax-dynamic-import', ['@babel/plugin-proposal-class-properties', { "loose": true }] ] } }, }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', }, 'postcss-loader', 'sass-loader' ] }) }, { test: /.(png|woff(2)?|eot|ttf|svg|gif)(\?[a-z0-9=\.]+)?$/, use: [ { loader: 'file-loader', options: { name: '../css/[hash].[ext]' } } ] }, { test : /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] } ] }, externals: { myApp: 'myApp', }, plugins: [ new ExtractTextPlugin(path.join('..', 'css', 'app.css')), new webpack.DefinePlugin({ '__DEV__' : JSON.stringify(true), '__API_HOST__' : JSON.stringify('http://localhost/my-app/'), }), ], }; if (process.env.NODE_ENV === 'production') { config.plugins.push( new webpack.optimize.UglifyJsPlugin({ sourceMap: false, compress: { sequences: true, conditionals: true, booleans: true, if_return: true, join_vars: true, drop_console: true }, output: { comments: false }, minimize: true }) ); } module.exports = config;
现在,让我们在前端显示用户数据。遍历/app/_devapp/app.js
文件并执行以下操作。借助webpack,我们将通过导入JS myApp变量来导入用户数据。
import React, { Component, Fragment } from 'react'; import { render } from 'react-dom'; import { asyncComponent } from 'react-async-component'; /** We are importing our index.php my app Vairaible */ import myApp from 'myApp'; class Myapp extends Component { render() { const { user : { name, email }, logged } = myApp; return ( <Fragment> <div className="dashboard"> {logged && <h2 className="status">Logged In</h2> } <h1 className="name"> {name}</h1> <p className="email">{email}</p> <p>API host variable {__API_HOST__}</p> </div> </Fragment> ) } } render(<Myapp/>, document.getElementById('app'));
/** We are importing our index.php myApp Vairaible */ import myApp from ‘myApp’;
运行npm install
以安装我们的依赖项。
我们将关注React应用程序文件中的更改,这将使我们能够在仍处于开发模式时将React文件用作捆绑文件。这是通过package.json
文件中的这一行完成的。
watch”: “webpack — colors — debug — display-chunk -w — env.NODE_ENV=development — mode development”
要显示我们的React App前端,我们需要通过terminal或cmd运行此命令npm run-script watch
。
生产
开发的最后一步是生产。但是首先,初始代码必须经过处理,编译和最小化的多个阶段。
为了完成我们在我们的 package.json
“build”: “webpack — progress — env.NODE_ENV=production — mode production”,
最后,我们需要执行命令"run-script build"
。之后,已编译的React代码将出现在“ app / assets / bundles /”文件夹中。该scss将被编译到“ app / assets / css”文件夹中。就这样!
要下载该项目的所有文件或浏览代码,请通过此Github链接访问存储库。
就是这样!如果您喜欢这篇文章,请确保在下面给我一些信息,并关注我以获取更多文章。
本文:React搭配PHP的使用方法, PHP 和 React.js一起使用, An advanced guide on how to setup a React and PHP