Windows下Web开发环境搭建

Windows下Web开发环境搭建

虽然Web程序大多运行在Linux服务器上,从兼容性角度来说,当然是在与服务器一致的环境下开发最好。但是我本地的机器是Windows系统,实在要用Linux的时候是采用虚拟机的方式。在虚拟机里面写代码着实麻烦,因此还是决定在Windows下搭建一套Web开发环境,方便测试。

我选择的Web开发组件是WNMP(Windows+Nginx+MySQL+PHP)。

Nginx下载安装启动#

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。目前我主要使用它的HTTP代理功能。在下载页面可以选择需要的版本下载,用于测试可以选择Mainline version,当前的最新版本是1.19.0。我直接使用Scoop安装。

安装好后在命令行窗口运行:start nginx。(注意直接运行nginx可能导致命令行无法退出)

如果出现以下错误信息:

1
2
3
4
nginx: [alert] could not open error log file: CreateFile() "logs/error.log" failed 
(3: The system cannot find the path specified)
2020/06/14 21:39:05 [emerg] 1444#13520: CreateFile() "C:\Users\awesome/conf/nginx.conf" failed
(3: The system cannot find the path specified)

说明当前路径不对,需要到安装目录下运行,我这里是[C:\Users\awesome\scoop\apps\nginx\current](file:///C:/Users/awesome/scoop/apps/nginx/current),或者利用-p选项指定安装路径也可以。允许通过防火墙后,就运行成功了。注意命令行界面是没有显示的。可以打开浏览器,访问http://localhost/,如果出现以下画面就说明安装成功了。

如果要停止Nginx,可以输入nginx -s stop,官网的简短的使用说明可以参考一下。

将Nginx注册成系统服务#

如果想让Nginx自动运行,最好的办法是把它注册成系统服务。我这里使用了winsw这个小工具。在下载页面选择合适的版本下载,我选的是WinSW.NET461.exe,可以同时下载一份配置文件sample-minimal.xml

下载好后,参考这篇博客进行配置。我就简单记录一下我的配置过程。将WinSW.NET461.exe复制一份到[nginx.exe所在目录](file:///C:/Users/awesome/scoop/apps/nginx/current),重命名为nginx-server.exe,在同目录下创建配置文件nginx-server.xml,内容如下:(配置文档

1
2
3
4
5
6
7
8
<service>
<id>nginx</id>
<name>Nginx</name>
<description>nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev. </description>
<executable>C:\Users\awesome\scoop\apps\nginx\current\nginx.exe</executable>
<startarguments>-p C:\Users\awesome\scoop\apps\nginx\current</startarguments>
<stoparguments>-p C:\Users\awesome\scoop\apps\nginx\current -s stop</stoparguments>
</service>

在当前目录下以管理员权限打开命令提示符运行以下命令安装服务:

1
2
C:\Users\awesome\scoop\apps\nginx\current>nginx-server.exe install
2020-06-14 22:00:46,957 INFO - Installing the service with id 'nginx'

在命令行下可以使用sc命令查询服务情况(注意该命令在PowerShell下需要改为sc.exe):

1
2
3
4
5
6
7
C:\Users\awesome\scoop\apps\nginx\current>sc query nginx   
SERVICE_NAME: nginx TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 1077 (0x435)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

sc query命令文档

可以看到目前Nginx服务是关闭的,如果之前运行的nginx.exe还在运行可以在任务管理器中结束任务。此时应该是无法访问localhost的了。接下来使用服务运行nginx。

1
2
3
C:\Users\awesome\scoop\apps\nginx\current>net start nginx
nginx 服务正在启动 .
nginx 服务已经启动成功。

或者直接使用sc命令:sc start nginx。这两个命令有略微的区别,sc命令会马上退出,此时nginx在等待启动,而net命令则会等到服务启动完成后再退出。

以后系统开机会自动运行Nginx服务,如果想取消可以使用sc config nginx start= demand命令改为手动运行。

sc config命令文档,注意等号后面的空格是比不可少的,参考这里

配置Nginx作为静态服务器#

假设现在写了一个简单的html文件,如何让nginx代理我的文件而不是默认的Welcome to Nginx!文件呢?下面记录几种方法:

假设HTML文件内容如下(来自Bootstrap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>

<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
</html>

保存到如下路径:[C:\Users\awesome\Documents\Projects\www\index.html](file:///C:/Users/awesome/Documents/Projects/www/index.html),双击html文件,可以正常打开(使用file协议)。在Nginx安装目录附近找一下,可以找到Nginx的HTML文件的[默认位置](file:///C:/Users/awesome/scoop/persist/nginx/html),把里面的html文件替换即可。

这时候打开localhost出现的就是新创建的HTML文件了。

如果不想更改文件夹位置,可以选择更改Nginx的配置,在[conf文件夹](file:///C:/Users/awesome/scoop/apps/nginx/current/conf)下有一个文件名为nginx.conf的文件。内容大致如下:

1
2
3
4
5
6
7
8
9
10
http {
...
server {
...
location / {
root html;
index index.html index.htm;
}
}
}

其中root指定的就是网站根目录对应的路径。root指令文档。其他配置可以参考Configuring NGINX and NGINX Plus as a Web Server

注意:Windows下路径中的\需要转义。我这里改成:

1
2
3
4
5
6
7
8
9
10
11
http {
...
server {
...
location / {
#root html;
root C:\\Users\\awesome\\Documents\\Projects\\www;
index index.html index.htm;
}
}
}

为了验证改动生效了,我把标题改成了Hello, new world!。重新启动nginx服务(可以先停止、再启动),打开localhost即可查看效果。

如果想再添加一个服务器,可以参考:Setting Up Virtual Servers

实际上,重新加载配置是不需要重新启动Nginx服务的,可以使用nginx -s reload 重新加载配置文件。(如果用服务方式启动,不要使用这种方式)

注意:start nginxnet start nginx两种启动方式不要混用,否则会启动多个nginx实例,造成冲突。

PHP下载安装运行#

PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。

打开PHP的下载页面,一般可以选择Non Thread Safe(nts)版本。解压安装好后,在[安装目录下](file:///C:/Users/awesome/scoop/apps/php/current)以管理员权限打开命令提示符,输入命令运行服务:

1
C:\Users\awesome\scoop\apps\php\current>php-cgi.exe -b localhost:9000

运行之后同样没有信息显示,按Ctrl+C可以退出。

Nginx配合PHP#

为了验证php服务运行正常,配置一下Nginx,使得它能解析php文件。同样打开nginx.conf,找到下面这段配置:

1
2
3
4
5
6
7
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

改为:

1
2
3
4
5
6
7
location ~ \.php$ {
root C:\\Users\\awesome\\Documents\\Projects\\www;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

大概解释一下原理吧。location指令用来定位,~表示后面的字符串是一个正则表达式,\.php$匹配所有以.php结尾的字符串,因此当网址以.php结尾时,就会启用下面的配置。前面提到nginx是一个代理服务器,因此它还可以把请求转发到别的服务上,参考Passing a Request to a Proxied Server。这里的fastcgi_pass就是其中一种。通常这些服务还需要读取一些其他信息如HTTP请求头、HTTP参数等,这些信息通过参数传递,定义在fastcgi_params文件中,感兴趣可以查看一下Nginx传递了哪些参数。参考这里$document_root等变量是Nginx内置的变量,指向root的地址,其他变量参考这里

为了方便测试,在首页添加一个链接到info.php。

index.html更改内容:

1
2
3
4
<h1>Hello, new world!</h1>
<ul>
<li><a href="info.php">PHP Info</a></li>
</ul>

同目录下新建info.php,内容:

1
<?php phpinfo(); ?>

显示效果:

说明PHP运行成功。

将PHP配置成系统服务#

把PHP配置成系统服务可以参考这里。同样简单记录一下我的配置方法。先下载winswxxfpm (winsw记得同时下载配置文件,xxfpm下载源代码即可)

将下载的xxfpm.exe 和 pthreadGC2.dll 扔进php-cgi.exe所在的目录,同样添加winsw的程序(php-server.exe)和配置文件(php-server.xml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<configuration>
<id>php</id>
<name>PHP</name>
<description>
PHP is a popular general-purpose scripting language that is especially suited to web development.
Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.
</description>
<executable>C:\Users\awesome\scoop\apps\php\current\xxfpm.exe</executable>
<startargument>"C:\Users\awesome\scoop\apps\php\current\php-cgi.exe"</startargument>
<startargument>-n</startargument>
<startargument>1</startargument>
<startargument>-i</startargument>
<startargument>127.0.0.1</startargument>
<startargument>-p</startargument>
<startargument>9000</startargument>

<stopexecutable>taskkill</stopexecutable>
<stopargument>/F</stopargument>
<stopargument>/IM</stopargument>
<stopargument>xxfpm.exe</stopargument>
</configuration>

放置好后大概这个效果:

以管理员权限运行cmd:

1
2
C:\Users\awesome\scoop\apps\php\current>php-server.exe install
2020-06-15 08:26:49,876 INFO - Installing the service with id 'php'

用PowerShell查询服务#

默认情况下sc命令在PowerShell是不起作用的。

1
2
3
4
PS C:\Users\awesome> Get-Alias -name sc
CommandType Name
----------- ----
Alias sc -> Set-Content

可以看到sc是Set-Content的别名。一种简单的方法是使用sc.exe

1
2
3
4
5
6
7
PS C:\Users\awesome> sc.exe query nginx
SERVICE_NAME: nginx TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

可惜的是sc别名是只读的,没法更改。

1
2
3
4
5
6
7
PS C:\Users\awesome> Set-Alias -Name sc -Value sc.exe
Set-Alias : 别名不可写入,因为别名 sc 为只读别名或常量,无法写入。
所在位置 行:1 字符: 1
+ Set-Alias -Name sc -Value sc.exe
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (sc:String) [Set-Alias], SessionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : AliasNotWritable,Microsoft.PowerShell.Commands.SetAliasCommand

查询PHP服务是否正确安装:

1
2
3
4
5
6
7
PS C:\Users\awesome> sc.exe query php
SERVICE_NAME: php TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 1077 (0x435)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

启动PHP服务,注意之前启动的要先关闭。

1
2
3
PS C:\Users\awesome> sudo net start php
php 服务正在启动 .
php 服务已经启动成功。

我这里使用了scoop提供的sudo命令,它可以暂时提升为管理员权限,如果没有这个命令可以再打开一个管理员权限的窗口。

MySQL安装配置#

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

可以在下载页面选择合适的版本下载安装,如果只需要命令行界面的话可以下载ZIP包,我同样使用Scoop命令行安装。由于MySQL自带了配置服务,因此安装非常简单,参考以下配置过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
PS C:\Users\awesome> sudo mysqld --install mysql --defaults-file="C:\Users\awesome\scoop\apps\mysql\current\my.ini"
Service successfully installed.
PS C:\Users\awesome> sudo net start mysql
mysql 服务正在启动 .
mysql 服务已经启动成功。
PS C:\Users\awesome> mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.20 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)

如果安装服务失败,可以尝试删除之前的安装文件,如Scoop的persist。

PHP连接MySQL#

首先启用PHP扩展。

打开[PHP安装目录](file:///C:/Users/awesome/scoop/apps/php/current),首先需要设置一下PHP的配置文件。找到php.ini-development文件,将它复制一份改名为php.ini。更改以下几个地方:

启用扩展目录:

1
2
3
4
5
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
;extension_dir = "./"
; On windows:
extension_dir = "ext"

设置时区:

1
2
3
4
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Asia/Shanghai

之后需要启用扩展可以在对应的模块取消注释或添加即可。

1
2
3
4
5
6
7
8
9
10
11
12
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;

; If you wish to have an extension loaded automatically, use the following
; syntax:
;
; extension=modulename
;
; For example:
;
; extension=mysqli

安装使用phpMyAdmin#

为了验证PHP与MySQL的正确安装配合,安装phpMyAdmin进行测试。同时方便对数据库进行管理。phpMyAdmin是一个非常受欢迎的基于web的MySQL数据库管理工具。它能够创建和删除数据库,创建/删除/修改表格,删除/编辑/新增字段,执行SQL脚本等。在官网下载即可。下载完成后解压,文件夹放到Nginx代理目录下。在index.html中添加一个入口:

1
2
3
4
<ul>
<li><a href="info.php">PHP Info</a></li>
<li><a href="phpMyAdmin-5.0.2-all-languages/">phpMyAdmin</a></li>
</ul>

这时候如果直接访问可能会出现403 Forbidden错误,这是因为默认的首页文件是index.html或index.htm,而phpMyAdmin提供的首页文件是index.php。我们可以改一下nginx的配置。

1
2
3
4
5
location / {
#root html;
root C:\\Users\\awesome\\Documents\\Projects\\www;
index index.html index.htm index.php;
}

重启一下Nginx,就可以访问了。

根据提示,在php.ini配置文件中启用mysqli扩展。

1
2
3
4
5
;extension=mbstring
;extension=exif ; Must be after mbstring as it depends on it
extension=mysqli
;extension=oci8_12c ; Use with Oracle Database 12c Instant Client
;extension=odbc

重新启动php服务:

1
2
3
4
5
6
7
PS C:\Users\awesome> sudo net stop php
php 服务正在停止.
php 服务已成功停止。

PS C:\Users\awesome> sudo net start php
php 服务正在启动 .
php 服务已经启动成功。

此时就能正常启动了。

默认是禁止空密码登录的,也可以启用。在phpMyAdmin根目录下找到config.sample.inc.php,复制为config.inc.php。

1
$cfg['Servers'][$i]['AllowNoPassword'] = true;

修改好后就可以直接用root账号登录了,密码不用输入即可。

Windows下Web开发环境搭建

https://blog.tootal.xyz/posts/webdev-setup/

作者

黄智权

本文发布于

2019-08-22

本文更新于

2019-08-22

许可协议

评论